GCC Code Coverage Report


Directory: ./
File: sql/sql_parse.cc
Date: 2022-12-13 11:44:05
Exec Total Coverage
Lines: 3557 3769 94.4%
Branches: 3925 6489 60.5%

Line Branch Exec Source
1 /* Copyright (c) 1999, 2022, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23 #include "sql/sql_parse.h"
24
25 #include <algorithm>
26 #include <atomic>
27 #include <climits>
28 #include <cstdint>
29 #include <cstdio>
30 #include <cstdlib>
31 #include <cstring>
32 #include <functional>
33 #include <iterator>
34 #include <memory>
35 #include <optional>
36 #include <string>
37 #include <utility>
38 #include <vector>
39
40 #include "my_config.h"
41 #ifdef HAVE_LSAN_DO_RECOVERABLE_LEAK_CHECK
42 #include <sanitizer/lsan_interface.h>
43 #endif
44
45 #include "dur_prop.h"
46 #include "field_types.h" // enum_field_types
47 #include "m_ctype.h"
48 #include "m_string.h"
49 #include "mem_root_deque.h"
50 #include "mutex_lock.h" // MUTEX_LOCK
51 #include "my_alloc.h"
52 #include "my_compiler.h"
53 #include "my_dbug.h"
54 #include "my_hostname.h"
55 #include "my_inttypes.h" // TODO: replace with cstdint
56 #include "my_io.h"
57 #include "my_loglevel.h"
58 #include "my_macros.h"
59 #include "my_psi_config.h"
60 #include "my_sys.h"
61 #include "my_table_map.h"
62 #include "my_thread_local.h"
63 #include "my_time.h"
64 #include "mysql/com_data.h"
65 #include "mysql/components/services/bits/plugin_audit_connection_types.h" // MYSQL_AUDIT_CONNECTION_CHANGE_USER
66 #include "mysql/components/services/bits/psi_statement_bits.h" // PSI_statement_info
67 #include "mysql/components/services/log_builtins.h" // LogErr
68 #include "mysql/plugin_audit.h"
69 #include "mysql/psi/mysql_mutex.h"
70 #include "mysql/psi/mysql_rwlock.h"
71 #include "mysql/psi/mysql_statement.h"
72 #include "mysql/service_mysql_alloc.h"
73 #include "mysql/udf_registration_types.h"
74 #include "mysql_version.h"
75 #include "mysqld_error.h"
76 #include "mysys_err.h" // EE_CAPACITY_EXCEEDED
77 #include "pfs_thread_provider.h"
78 #include "prealloced_array.h"
79 #include "scope_guard.h"
80 #include "sql/auth/auth_acls.h"
81 #include "sql/auth/sql_security_ctx.h"
82 #include "sql/binlog.h" // purge_source_logs
83 #include "sql/clone_handler.h"
84 #include "sql/comp_creator.h"
85 #include "sql/create_field.h"
86 #include "sql/current_thd.h"
87 #include "sql/dd/cache/dictionary_client.h" // dd::cache::Dictionary_client::Auto_releaser
88 #include "sql/dd/dd.h" // dd::get_dictionary
89 #include "sql/dd/dd_schema.h" // Schema_MDL_locker
90 #include "sql/dd/dictionary.h" // dd::Dictionary::is_system_view_name
91 #include "sql/dd/info_schema/table_stats.h"
92 #include "sql/dd/types/column.h"
93 #include "sql/debug_sync.h" // DEBUG_SYNC
94 #include "sql/derror.h" // ER_THD
95 #include "sql/discrete_interval.h"
96 #include "sql/error_handler.h" // Strict_error_handler
97 #include "sql/events.h" // Events
98 #include "sql/field.h"
99 #include "sql/gis/srid.h"
100 #include "sql/item.h"
101 #include "sql/item_cmpfunc.h"
102 #include "sql/item_func.h"
103 #include "sql/item_subselect.h"
104 #include "sql/item_timefunc.h" // Item_func_unix_timestamp
105 #include "sql/key_spec.h" // Key_spec
106 #include "sql/locked_tables_list.h"
107 #include "sql/log.h" // query_logger
108 #include "sql/log_event.h" // slave_execute_deferred_events
109 #include "sql/mdl.h"
110 #include "sql/mem_root_array.h"
111 #include "sql/mysqld.h" // stage_execution_of_init_command
112 #include "sql/mysqld_thd_manager.h" // Find_thd_with_id
113 #include "sql/nested_join.h"
114 #include "sql/opt_hints.h"
115 #include "sql/opt_trace.h" // Opt_trace_start
116 #include "sql/parse_location.h"
117 #include "sql/parse_tree_node_base.h"
118 #include "sql/parse_tree_nodes.h"
119 #include "sql/parser_yystype.h"
120 #include "sql/persisted_variable.h"
121 #include "sql/protocol.h"
122 #include "sql/protocol_classic.h"
123 #include "sql/psi_memory_key.h"
124 #include "sql/query_options.h"
125 #include "sql/query_result.h"
126 #include "sql/resourcegroups/resource_group_basic_types.h"
127 #include "sql/resourcegroups/resource_group_mgr.h" // Resource_group_mgr::instance
128 #include "sql/rpl_context.h"
129 #include "sql/rpl_filter.h" // rpl_filter
130 #include "sql/rpl_group_replication.h" // group_replication_start
131 #include "sql/rpl_gtid.h"
132 #include "sql/rpl_handler.h" // launch_hook_trans_begin
133 #include "sql/rpl_replica.h" // change_master_cmd
134 #include "sql/rpl_source.h" // register_slave
135 #include "sql/rpl_utility.h"
136 #include "sql/session_tracker.h"
137 #include "sql/set_var.h"
138 #include "sql/sp.h" // sp_create_routine
139 #include "sql/sp_cache.h" // sp_cache_enforce_limit
140 #include "sql/sp_head.h" // sp_head
141 #include "sql/sp_instr.h"
142 #include "sql/sp_rcontext.h"
143 #include "sql/sql_admin.h"
144 #include "sql/sql_alter.h"
145 #include "sql/sql_audit.h" // MYSQL_AUDIT_NOTIFY_CONNECTION_CHANGE_USER
146 #include "sql/sql_backup_lock.h"
147 #include "sql/sql_base.h" // find_temporary_table
148 #include "sql/sql_binlog.h" // mysql_client_binlog_statement
149 #include "sql/sql_check_constraint.h"
150 #include "sql/sql_class.h"
151 #include "sql/sql_cmd.h"
152 #include "sql/sql_connect.h" // decrease_user_connections
153 #include "sql/sql_const.h"
154 #include "sql/sql_db.h" // mysql_change_db
155 #include "sql/sql_digest.h"
156 #include "sql/sql_digest_stream.h"
157 #include "sql/sql_error.h"
158 #include "sql/sql_handler.h" // mysql_ha_rm_tables
159 #include "sql/sql_help.h" // mysqld_help
160 #include "sql/sql_lex.h"
161 #include "sql/sql_list.h"
162 #include "sql/sql_prepare.h" // mysql_stmt_execute
163 #include "sql/sql_profile.h"
164 #include "sql/sql_query_rewrite.h" // invoke_pre_parse_rewrite_plugins
165 #include "sql/sql_reload.h" // handle_reload_request
166 #include "sql/sql_rename.h" // mysql_rename_tables
167 #include "sql/sql_rewrite.h" // mysql_rewrite_query
168 #include "sql/sql_show.h" // find_schema_table
169 #include "sql/sql_table.h" // mysql_create_table
170 #include "sql/sql_trigger.h" // add_table_for_trigger
171 #include "sql/sql_udf.h"
172 #include "sql/sql_view.h" // mysql_create_view
173 #include "sql/sql_zip_dict.h" // mysqld_create_zip_dict, mysqld_drop_zip_dict
174 #include "sql/strfunc.h"
175 #include "sql/system_variables.h" // System_status_var
176 #include "sql/table.h"
177 #include "sql/table_cache.h" // table_cache_manager
178 #include "sql/thd_raii.h"
179 #include "sql/transaction.h" // trans_rollback_implicit
180 #include "sql/transaction_info.h"
181 #include "sql/userstat.h"
182 #include "sql_string.h"
183 #include "template_utils.h"
184 #include "thr_lock.h"
185 #include "violite.h"
186
187 #ifdef WITH_LOCK_ORDER
188 #include "sql/debug_lock_order.h"
189 #endif /* WITH_LOCK_ORDER */
190
191 #ifdef WITH_WSREP
192 #include "wsrep_binlog.h"
193 #include "wsrep_mysqld.h"
194 #include "wsrep_sst.h"
195 #include "wsrep_thd.h"
196 #include "wsrep_trans_observer.h"
197
198 static bool wsrep_dispatch_sql_command(THD *thd, const char *rawbuf,
199 uint length, Parser_state *parser_state,
200 bool update_userstat);
201 #endif /* WITH_WSREP */
202
203 namespace resourcegroups {
204 class Resource_group;
205 } // namespace resourcegroups
206 struct mysql_rwlock_t;
207
208 namespace dd {
209 class Schema;
210 } // namespace dd
211
212 namespace dd {
213 class Abstract_table;
214 } // namespace dd
215
216 using std::max;
217
218 /**
219 @defgroup Runtime_Environment Runtime Environment
220 @{
221 */
222
223 /* Used in error handling only */
224 #define SP_COM_STRING(LP) \
225 ((LP)->sql_command == SQLCOM_CREATE_SPFUNCTION || \
226 (LP)->sql_command == SQLCOM_ALTER_FUNCTION || \
227 (LP)->sql_command == SQLCOM_SHOW_CREATE_FUNC || \
228 (LP)->sql_command == SQLCOM_DROP_FUNCTION \
229 ? "FUNCTION" \
230 : "PROCEDURE")
231
232 static void sql_kill(THD *thd, my_thread_id id, bool only_kill_query);
233
234 const std::array<const std::string, COM_END + 1> Command_names::m_names = {
235 "Sleep",
236 "Quit",
237 "Init DB",
238 "Query",
239 "Field List",
240 "Create DB",
241 "Drop DB",
242 "Refresh",
243 "Shutdown",
244 "Statistics",
245 "Processlist",
246 "Connect",
247 "Kill",
248 "Debug",
249 "Ping",
250 "Time",
251 "Delayed insert",
252 "Change user",
253 "Binlog Dump",
254 "Table Dump",
255 "Connect Out",
256 "Register Replica",
257 "Prepare",
258 "Execute",
259 "Long Data",
260 "Close stmt",
261 "Reset stmt",
262 "Set option",
263 "Fetch",
264 "Daemon",
265 "Binlog Dump GTID",
266 "Reset Connection",
267 "clone",
268 "Group Replication Data Stream subscription",
269 "Error" // Last command number
270 };
271
272 14273 const std::string &Command_names::translate(const System_variables &sysvars) {
273 14273 terminology_use_previous::enum_compatibility_version version =
274 static_cast<terminology_use_previous::enum_compatibility_version>(
275 14273 sysvars.terminology_use_previous);
276
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 14260 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
14273 if (version != terminology_use_previous::NONE && version <= m_replace_version)
277 13 return m_replace_str;
278 14260 return m_names[m_replace_com];
279 }
280
281 101812 const std::string &Command_names::str_session(enum_server_command cmd) {
282
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 101812 times.
101812 assert(current_thd);
283
5/6
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 101792 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 101792 times.
✓ Branch 5 taken 20 times.
101812 if (cmd != m_replace_com || current_thd == nullptr) return m_names[cmd];
284 20 return translate(current_thd->variables);
285 }
286
287 39342272 const std::string &Command_names::str_global(enum_server_command cmd) {
288
2/2
✓ Branch 0 taken 39328333 times.
✓ Branch 1 taken 13939 times.
39342272 if (cmd != m_replace_com) return m_names[cmd];
289 13939 return translate(global_system_variables);
290 }
291
292 const std::string Command_names::m_replace_str{"Register Slave"};
293
294 21364066 bool command_satisfy_acl_cache_requirement(unsigned command) {
295
2/2
✓ Branch 0 taken 37676 times.
✓ Branch 1 taken 21326390 times.
21401742 return !((sql_command_flags[command] & CF_REQUIRE_ACL_CACHE) > 0 &&
296
1/2
✓ Branch 0 taken 38093 times.
✗ Branch 1 not taken.
21401742 skip_grant_tables());
297 }
298
299 /**
300 Returns true if all tables should be ignored.
301 */
302 533598 bool all_tables_not_ok(THD *thd, TABLE_LIST *tables) {
303 533598 Rpl_filter *rpl_filter = thd->rli_slave->rpl_filter;
304
305
6/6
✓ Branch 0 taken 1554 times.
✓ Branch 1 taken 531895 times.
✓ Branch 2 taken 755 times.
✓ Branch 3 taken 799 times.
✓ Branch 4 taken 752 times.
✓ Branch 5 taken 3 times.
534391 return rpl_filter->is_on() && tables && !thd->sp_runtime_ctx &&
306
2/2
✓ Branch 0 taken 321 times.
✓ Branch 1 taken 472 times.
534242 !rpl_filter->tables_ok(thd->db().str, tables);
307 }
308
309 /**
310 Checks whether the event for the given database, db, should
311 be ignored or not. This is done by checking whether there are
312 active rules in ignore_db or in do_db containers. If there
313 are, then check if there is a match, if not then check the
314 wild_do rules.
315
316 NOTE: This means that when using this function replicate-do-db
317 and replicate-ignore-db take precedence over wild do
318 rules.
319
320 @param thd Thread handle.
321 @param db Database name used while evaluating the filtering
322 rules.
323 @param sql_cmd Represents the current query that needs to be
324 verified against the database filter rules.
325 @return true Query should not be filtered out from the execution.
326 false Query should be filtered out from the execution.
327
328 */
329 536030 inline bool check_database_filters(THD *thd, const char *db,
330 enum_sql_command sql_cmd) {
331
1/2
✓ Branch 0 taken 536780 times.
✗ Branch 1 not taken.
536030 DBUG_TRACE;
332
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 536780 times.
536780 assert(thd->slave_thread);
333
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 536769 times.
536780 if (!db) return true;
334 536769 Rpl_filter *rpl_filter = thd->rli_slave->rpl_filter;
335
336 536769 bool need_increase_counter = true;
337
3/3
✓ Branch 0 taken 349002 times.
✓ Branch 1 taken 1008 times.
✓ Branch 2 taken 186759 times.
536769 switch (sql_cmd) {
338 349002 case SQLCOM_BEGIN:
339 case SQLCOM_COMMIT:
340 case SQLCOM_SAVEPOINT:
341 case SQLCOM_ROLLBACK:
342 case SQLCOM_ROLLBACK_TO_SAVEPOINT:
343 349002 return true;
344 1008 case SQLCOM_XA_START:
345 case SQLCOM_XA_END:
346 case SQLCOM_XA_COMMIT:
347 case SQLCOM_XA_ROLLBACK:
348 1008 need_increase_counter = false;
349 187767 default:
350 187767 break;
351 }
352
353
1/2
✓ Branch 0 taken 187399 times.
✗ Branch 1 not taken.
187767 bool db_ok = rpl_filter->db_ok(db, need_increase_counter);
354 /*
355 No filters exist in ignore/do_db ? Then, just check
356 wild_do_table filtering for 'DATABASE' related
357 statements (CREATE/DROP/ATLER DATABASE)
358 */
359
9/10
✓ Branch 0 taken 187132 times.
✓ Branch 1 taken 267 times.
✓ Branch 2 taken 187154 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 186762 times.
✓ Branch 5 taken 419 times.
✓ Branch 6 taken 186813 times.
✓ Branch 7 taken 57 times.
✓ Branch 8 taken 186829 times.
✓ Branch 9 taken 727 times.
374269 if (db_ok && (rpl_filter->get_do_db()->is_empty() &&
360
1/2
✓ Branch 0 taken 186726 times.
✗ Branch 1 not taken.
186762 rpl_filter->get_ignore_db()->is_empty())) {
361
2/2
✓ Branch 0 taken 1630 times.
✓ Branch 1 taken 185199 times.
186829 switch (sql_cmd) {
362 1630 case SQLCOM_CREATE_DB:
363 case SQLCOM_ALTER_DB:
364 case SQLCOM_DROP_DB:
365
1/2
✓ Branch 0 taken 1630 times.
✗ Branch 1 not taken.
1630 db_ok = rpl_filter->db_ok_with_wild_table(db);
366 186829 default:
367 186829 break;
368 }
369 }
370 187556 return db_ok;
371 536569 }
372
373 162 bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables) {
374
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 88 times.
268 for (TABLE_LIST *table = tables; table; table = table->next_global) {
375
2/4
✓ Branch 0 taken 180 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 180 times.
✗ Branch 3 not taken.
180 assert(table->db && table->table_name);
376 /*
377 Update on performance_schema and temp tables are allowed
378 in readonly mode.
379 */
380
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 58 times.
160 if (table->updating && !find_temporary_table(thd, table) &&
381 #ifdef WITH_WSREP
382
2/2
✓ Branch 0 taken 82 times.
✓ Branch 1 taken 20 times.
102 !is_wsrep_system_table(table->db, table->db_length, table->table_name,
383
4/4
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 74 times.
✓ Branch 3 taken 106 times.
340 table->table_name_length) &&
384 #endif /* WITH_WSREP */
385
2/2
✓ Branch 0 taken 74 times.
✓ Branch 1 taken 8 times.
82 !is_perfschema_db(table->db, table->db_length))
386 74 return true;
387 }
388 88 return false;
389 }
390
391 /**
392 Returns whether the command in thd->lex->sql_command should cause an
393 implicit commit. An active transaction should be implicitly committed if the
394 statement requires so.
395
396 @param thd Thread handle.
397 @param mask Bitmask used for the SQL command match.
398
399 @retval true This statement shall cause an implicit commit.
400 @retval false This statement shall not cause an implicit commit.
401 */
402 86165711 bool stmt_causes_implicit_commit(const THD *thd, uint mask) {
403
1/2
✓ Branch 0 taken 86169627 times.
✗ Branch 1 not taken.
86165711 DBUG_TRACE;
404 86169627 const LEX *lex = thd->lex;
405
406
6/6
✓ Branch 0 taken 11686031 times.
✓ Branch 1 taken 74483596 times.
✓ Branch 2 taken 59782 times.
✓ Branch 3 taken 11626202 times.
✓ Branch 4 taken 74543352 times.
✓ Branch 5 taken 11626228 times.
97855611 if ((sql_command_flags[lex->sql_command] & mask) == 0 ||
407 11686031 thd->is_plugin_fake_ddl())
408 74543352 return false;
409
410
6/6
✓ Branch 0 taken 710879 times.
✓ Branch 1 taken 2884664 times.
✓ Branch 2 taken 6011712 times.
✓ Branch 3 taken 101080 times.
✓ Branch 4 taken 4089 times.
✓ Branch 5 taken 1913804 times.
11626228 switch (lex->sql_command) {
411 710879 case SQLCOM_DROP_TABLE:
412 710879 return !lex->drop_temporary;
413 2884664 case SQLCOM_ALTER_TABLE:
414 case SQLCOM_CREATE_TABLE:
415 /* If CREATE TABLE of non-temporary table or without
416 START TRANSACTION, do implicit commit */
417
2/2
✓ Branch 0 taken 2694016 times.
✓ Branch 1 taken 190648 times.
5578680 return (lex->create_info->options & HA_LEX_CREATE_TMP_TABLE ||
418
2/2
✓ Branch 0 taken 271 times.
✓ Branch 1 taken 2693745 times.
5578680 lex->create_info->m_transactional_ddl) == 0;
419 6011712 case SQLCOM_SET_OPTION:
420 /* Implicitly commit a transaction started by a SET statement */
421 6011712 return lex->autocommit;
422 101080 case SQLCOM_RESET:
423 101080 return lex->option_type != OPT_PERSIST;
424 4089 case SQLCOM_STOP_GROUP_REPLICATION:
425 4089 return lex->was_replication_command_executed();
426 1913804 default:
427 1913804 return true;
428 }
429 86169580 }
430
431 /**
432 Mark all commands that somehow changes a table.
433
434 This is used to check number of updates / hour.
435
436 sql_command is actually set to SQLCOM_END sometimes
437 so we need the +1 to include it in the array.
438
439 See COMMAND_FLAG_xxx for different type of commands
440 2 - query that returns meaningful ROW_COUNT() -
441 a number of modified rows
442 */
443
444 uint sql_command_flags[SQLCOM_END + 1];
445 uint server_command_flags[COM_END + 1];
446
447 9736 void init_sql_command_flags() {
448 /* Initialize the server command flags array. */
449 9736 memset(server_command_flags, 0, sizeof(server_command_flags));
450
451 9736 server_command_flags[COM_SLEEP] = CF_ALLOW_PROTOCOL_PLUGIN;
452 9736 server_command_flags[COM_INIT_DB] = CF_ALLOW_PROTOCOL_PLUGIN;
453 9736 server_command_flags[COM_QUERY] = CF_ALLOW_PROTOCOL_PLUGIN;
454 9736 server_command_flags[COM_FIELD_LIST] = CF_ALLOW_PROTOCOL_PLUGIN;
455 9736 server_command_flags[COM_REFRESH] = CF_ALLOW_PROTOCOL_PLUGIN;
456 9736 server_command_flags[COM_STATISTICS] = CF_SKIP_QUESTIONS;
457 9736 server_command_flags[COM_PROCESS_KILL] = CF_ALLOW_PROTOCOL_PLUGIN;
458 9736 server_command_flags[COM_PING] = CF_SKIP_QUESTIONS;
459 9736 server_command_flags[COM_STMT_PREPARE] =
460 CF_SKIP_QUESTIONS | CF_ALLOW_PROTOCOL_PLUGIN;
461 9736 server_command_flags[COM_STMT_EXECUTE] = CF_ALLOW_PROTOCOL_PLUGIN;
462 9736 server_command_flags[COM_STMT_SEND_LONG_DATA] = CF_ALLOW_PROTOCOL_PLUGIN;
463 9736 server_command_flags[COM_STMT_CLOSE] =
464 CF_SKIP_QUESTIONS | CF_ALLOW_PROTOCOL_PLUGIN;
465 9736 server_command_flags[COM_STMT_RESET] =
466 CF_SKIP_QUESTIONS | CF_ALLOW_PROTOCOL_PLUGIN;
467 9736 server_command_flags[COM_STMT_FETCH] = CF_ALLOW_PROTOCOL_PLUGIN;
468 9736 server_command_flags[COM_RESET_CONNECTION] = CF_ALLOW_PROTOCOL_PLUGIN;
469 9736 server_command_flags[COM_END] = CF_ALLOW_PROTOCOL_PLUGIN;
470
471 #ifdef WITH_WSREP
472 9736 server_command_flags[COM_STATISTICS] |= CF_SKIP_WSREP_CHECK;
473 9736 server_command_flags[COM_PING] |= CF_SKIP_WSREP_CHECK;
474 9736 server_command_flags[COM_STMT_PREPARE] |= CF_SKIP_WSREP_CHECK;
475 9736 server_command_flags[COM_STMT_EXECUTE] |= CF_SKIP_WSREP_CHECK;
476 9736 server_command_flags[COM_STMT_FETCH] |= CF_SKIP_WSREP_CHECK;
477 9736 server_command_flags[COM_STMT_CLOSE] |= CF_SKIP_WSREP_CHECK;
478 9736 server_command_flags[COM_STMT_RESET] |= CF_SKIP_WSREP_CHECK;
479 9736 server_command_flags[COM_STMT_SEND_LONG_DATA] |= CF_SKIP_WSREP_CHECK;
480 9736 server_command_flags[COM_QUIT] |= CF_SKIP_WSREP_CHECK;
481 9736 server_command_flags[COM_PROCESS_INFO] |= CF_SKIP_WSREP_CHECK;
482 9736 server_command_flags[COM_PROCESS_KILL] |= CF_SKIP_WSREP_CHECK;
483 9736 server_command_flags[COM_SLEEP] |= CF_SKIP_WSREP_CHECK;
484 9736 server_command_flags[COM_TIME] |= CF_SKIP_WSREP_CHECK;
485 9736 server_command_flags[COM_INIT_DB] |= CF_SKIP_WSREP_CHECK;
486 9736 server_command_flags[COM_END] |= CF_SKIP_WSREP_CHECK;
487 9736 server_command_flags[COM_FIELD_LIST] |= CF_SKIP_WSREP_CHECK;
488
489 /*
490 COM_QUERY and COM_SET_OPTION are allowed to pass the early COM_xxx filter,
491 they're checked later in mysql_execute_command().
492 */
493 9736 server_command_flags[COM_QUERY] |= CF_SKIP_WSREP_CHECK;
494 9736 server_command_flags[COM_SET_OPTION] |= CF_SKIP_WSREP_CHECK;
495 #endif /* WITH_WSREP */
496
497 /* Initialize the sql command flags array. */
498 9736 memset(sql_command_flags, 0, sizeof(sql_command_flags));
499
500 /*
501 In general, DDL statements do not generate row events and do not go
502 through a cache before being written to the binary log. However, the
503 CREATE TABLE...SELECT is an exception because it may generate row
504 events. For that reason, the SQLCOM_CREATE_TABLE which represents
505 a CREATE TABLE, including the CREATE TABLE...SELECT, has the
506 CF_CAN_GENERATE_ROW_EVENTS flag. The distinction between a regular
507 CREATE TABLE and the CREATE TABLE...SELECT is made in other parts of
508 the code, in particular in the Query_log_event's constructor.
509 */
510 9736 sql_command_flags[SQLCOM_CREATE_TABLE] =
511 CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_AUTO_COMMIT_TRANS |
512 CF_CAN_GENERATE_ROW_EVENTS;
513 9736 sql_command_flags[SQLCOM_CREATE_INDEX] =
514 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
515 9736 sql_command_flags[SQLCOM_ALTER_TABLE] =
516 CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS;
517 9736 sql_command_flags[SQLCOM_TRUNCATE] =
518 CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS;
519 9736 sql_command_flags[SQLCOM_DROP_TABLE] = CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
520 9736 sql_command_flags[SQLCOM_LOAD] =
521 CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_CAN_GENERATE_ROW_EVENTS;
522 9736 sql_command_flags[SQLCOM_CREATE_DB] = CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
523 9736 sql_command_flags[SQLCOM_DROP_DB] = CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
524 9736 sql_command_flags[SQLCOM_ALTER_DB] = CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
525 9736 sql_command_flags[SQLCOM_RENAME_TABLE] =
526 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
527 9736 sql_command_flags[SQLCOM_DROP_INDEX] = CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
528 9736 sql_command_flags[SQLCOM_CREATE_VIEW] =
529 CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_AUTO_COMMIT_TRANS;
530 9736 sql_command_flags[SQLCOM_DROP_VIEW] = CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
531 9736 sql_command_flags[SQLCOM_CREATE_TRIGGER] =
532 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
533 9736 sql_command_flags[SQLCOM_DROP_TRIGGER] =
534 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
535 9736 sql_command_flags[SQLCOM_CREATE_EVENT] =
536 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
537 9736 sql_command_flags[SQLCOM_ALTER_EVENT] =
538 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
539 9736 sql_command_flags[SQLCOM_DROP_EVENT] = CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
540 9736 sql_command_flags[SQLCOM_IMPORT] = CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
541
542 9736 sql_command_flags[SQLCOM_UPDATE] = CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
543 CF_CAN_GENERATE_ROW_EVENTS |
544 CF_OPTIMIZER_TRACE | CF_CAN_BE_EXPLAINED;
545 9736 sql_command_flags[SQLCOM_CREATE_COMPRESSION_DICTIONARY] =
546 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
547 9736 sql_command_flags[SQLCOM_DROP_COMPRESSION_DICTIONARY] =
548 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
549 9736 sql_command_flags[SQLCOM_UPDATE_MULTI] =
550 CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_CAN_GENERATE_ROW_EVENTS |
551 CF_OPTIMIZER_TRACE | CF_CAN_BE_EXPLAINED;
552 // This is INSERT VALUES(...), can be VALUES(stored_func()) so we trace it
553 9736 sql_command_flags[SQLCOM_INSERT] = CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
554 CF_CAN_GENERATE_ROW_EVENTS |
555 CF_OPTIMIZER_TRACE | CF_CAN_BE_EXPLAINED;
556 9736 sql_command_flags[SQLCOM_INSERT_SELECT] =
557 CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_CAN_GENERATE_ROW_EVENTS |
558 CF_OPTIMIZER_TRACE | CF_CAN_BE_EXPLAINED;
559 9736 sql_command_flags[SQLCOM_DELETE] = CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
560 CF_CAN_GENERATE_ROW_EVENTS |
561 CF_OPTIMIZER_TRACE | CF_CAN_BE_EXPLAINED;
562 9736 sql_command_flags[SQLCOM_DELETE_MULTI] =
563 CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_CAN_GENERATE_ROW_EVENTS |
564 CF_OPTIMIZER_TRACE | CF_CAN_BE_EXPLAINED;
565 9736 sql_command_flags[SQLCOM_REPLACE] = CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
566 CF_CAN_GENERATE_ROW_EVENTS |
567 CF_OPTIMIZER_TRACE | CF_CAN_BE_EXPLAINED;
568 9736 sql_command_flags[SQLCOM_REPLACE_SELECT] =
569 CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_CAN_GENERATE_ROW_EVENTS |
570 CF_OPTIMIZER_TRACE | CF_CAN_BE_EXPLAINED;
571 9736 sql_command_flags[SQLCOM_SELECT] =
572 CF_REEXECUTION_FRAGILE | CF_CAN_GENERATE_ROW_EVENTS | CF_OPTIMIZER_TRACE |
573 CF_HAS_RESULT_SET | CF_CAN_BE_EXPLAINED;
574 // (1) so that subquery is traced when doing "SET @var = (subquery)"
575 /*
576 @todo SQLCOM_SET_OPTION should have CF_CAN_GENERATE_ROW_EVENTS
577 set, because it may invoke a stored function that generates row
578 events. /Sven
579 */
580 9736 sql_command_flags[SQLCOM_SET_OPTION] =
581 CF_REEXECUTION_FRAGILE | CF_AUTO_COMMIT_TRANS |
582 CF_CAN_GENERATE_ROW_EVENTS | CF_OPTIMIZER_TRACE; // (1)
583 // (1) so that subquery is traced when doing "DO @var := (subquery)"
584 9736 sql_command_flags[SQLCOM_DO] = CF_REEXECUTION_FRAGILE |
585 CF_CAN_GENERATE_ROW_EVENTS |
586 CF_OPTIMIZER_TRACE; // (1)
587
588 9736 sql_command_flags[SQLCOM_SET_PASSWORD] =
589 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_NEEDS_AUTOCOMMIT_OFF |
590 CF_POTENTIAL_ATOMIC_DDL | CF_DISALLOW_IN_RO_TRANS;
591
592 9736 sql_command_flags[SQLCOM_SHOW_STATUS_PROC] =
593 CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET;
594 9736 sql_command_flags[SQLCOM_SHOW_STATUS] =
595 CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET;
596 9736 sql_command_flags[SQLCOM_SHOW_DATABASES] =
597 CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET;
598 9736 sql_command_flags[SQLCOM_SHOW_TRIGGERS] =
599 CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET;
600 9736 sql_command_flags[SQLCOM_SHOW_EVENTS] =
601 CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET;
602 9736 sql_command_flags[SQLCOM_SHOW_OPEN_TABLES] =
603 CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET;
604 9736 sql_command_flags[SQLCOM_SHOW_PLUGINS] = CF_STATUS_COMMAND;
605 9736 sql_command_flags[SQLCOM_SHOW_FIELDS] =
606 CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET;
607 9736 sql_command_flags[SQLCOM_SHOW_KEYS] =
608 CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET;
609 9736 sql_command_flags[SQLCOM_SHOW_VARIABLES] =
610 CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET;
611 9736 sql_command_flags[SQLCOM_SHOW_CHARSETS] =
612 CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET;
613 9736 sql_command_flags[SQLCOM_SHOW_COLLATIONS] =
614 CF_STATUS_COMMAND | CF_HAS_RESULT_SET | CF_REEXECUTION_FRAGILE;
615 9736 sql_command_flags[SQLCOM_SHOW_BINLOGS] = CF_STATUS_COMMAND;
616 9736 sql_command_flags[SQLCOM_SHOW_SLAVE_HOSTS] = CF_STATUS_COMMAND;
617 9736 sql_command_flags[SQLCOM_SHOW_BINLOG_EVENTS] = CF_STATUS_COMMAND;
618 9736 sql_command_flags[SQLCOM_SHOW_STORAGE_ENGINES] = CF_STATUS_COMMAND;
619 9736 sql_command_flags[SQLCOM_SHOW_PRIVILEGES] = CF_STATUS_COMMAND;
620 9736 sql_command_flags[SQLCOM_SHOW_WARNS] = CF_STATUS_COMMAND | CF_DIAGNOSTIC_STMT;
621 9736 sql_command_flags[SQLCOM_SHOW_ERRORS] =
622 CF_STATUS_COMMAND | CF_DIAGNOSTIC_STMT;
623 9736 sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS] = CF_STATUS_COMMAND;
624 9736 sql_command_flags[SQLCOM_SHOW_ENGINE_MUTEX] = CF_STATUS_COMMAND;
625 9736 sql_command_flags[SQLCOM_SHOW_ENGINE_LOGS] = CF_STATUS_COMMAND;
626 9736 sql_command_flags[SQLCOM_SHOW_PROCESSLIST] = CF_STATUS_COMMAND;
627 9736 sql_command_flags[SQLCOM_SHOW_GRANTS] = CF_STATUS_COMMAND;
628 9736 sql_command_flags[SQLCOM_SHOW_CREATE_DB] = CF_STATUS_COMMAND;
629 9736 sql_command_flags[SQLCOM_SHOW_CREATE] = CF_STATUS_COMMAND;
630 9736 sql_command_flags[SQLCOM_SHOW_MASTER_STAT] = CF_STATUS_COMMAND;
631 9736 sql_command_flags[SQLCOM_SHOW_SLAVE_STAT] = CF_STATUS_COMMAND;
632 9736 sql_command_flags[SQLCOM_SHOW_CREATE_PROC] = CF_STATUS_COMMAND;
633 9736 sql_command_flags[SQLCOM_SHOW_CREATE_FUNC] = CF_STATUS_COMMAND;
634 9736 sql_command_flags[SQLCOM_SHOW_CREATE_TRIGGER] = CF_STATUS_COMMAND;
635 9736 sql_command_flags[SQLCOM_SHOW_STATUS_FUNC] =
636 CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET;
637 9736 sql_command_flags[SQLCOM_SHOW_PROC_CODE] = CF_STATUS_COMMAND;
638 9736 sql_command_flags[SQLCOM_SHOW_FUNC_CODE] = CF_STATUS_COMMAND;
639 9736 sql_command_flags[SQLCOM_SHOW_CREATE_EVENT] = CF_STATUS_COMMAND;
640 9736 sql_command_flags[SQLCOM_SHOW_PROFILES] = CF_STATUS_COMMAND;
641 9736 sql_command_flags[SQLCOM_SHOW_PROFILE] = CF_STATUS_COMMAND;
642 9736 sql_command_flags[SQLCOM_BINLOG_BASE64_EVENT] =
643 CF_STATUS_COMMAND | CF_CAN_GENERATE_ROW_EVENTS;
644
645 9736 sql_command_flags[SQLCOM_SHOW_TABLES] =
646 (CF_STATUS_COMMAND | CF_SHOW_TABLE_COMMAND | CF_HAS_RESULT_SET |
647 CF_REEXECUTION_FRAGILE);
648 9736 sql_command_flags[SQLCOM_SHOW_TABLE_STATUS] =
649 (CF_STATUS_COMMAND | CF_SHOW_TABLE_COMMAND | CF_HAS_RESULT_SET |
650 CF_REEXECUTION_FRAGILE);
651 9736 sql_command_flags[SQLCOM_SHOW_USER_STATS] = CF_STATUS_COMMAND;
652 9736 sql_command_flags[SQLCOM_SHOW_TABLE_STATS] = CF_STATUS_COMMAND;
653 9736 sql_command_flags[SQLCOM_SHOW_INDEX_STATS] = CF_STATUS_COMMAND;
654 9736 sql_command_flags[SQLCOM_SHOW_CLIENT_STATS] = CF_STATUS_COMMAND;
655 9736 sql_command_flags[SQLCOM_SHOW_THREAD_STATS] = CF_STATUS_COMMAND;
656 /**
657 ACL DDLs do not access data-dictionary tables. However, they still
658 need to be marked to avoid autocommit. This is necessary because
659 code which saves GTID state or slave state in the system tables
660 at commit time does statement commit on low-level (see
661 System_table_access::close_table()) and thus can pre-maturely commit
662 DDL otherwise.
663 */
664 9736 sql_command_flags[SQLCOM_CREATE_USER] =
665 CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
666 9736 sql_command_flags[SQLCOM_RENAME_USER] =
667 CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
668 9736 sql_command_flags[SQLCOM_DROP_USER] =
669 CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
670 9736 sql_command_flags[SQLCOM_ALTER_USER] =
671 CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
672 9736 sql_command_flags[SQLCOM_GRANT] =
673 CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
674 9736 sql_command_flags[SQLCOM_REVOKE] =
675 CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
676 9736 sql_command_flags[SQLCOM_REVOKE_ALL] =
677 CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
678 9736 sql_command_flags[SQLCOM_ALTER_USER_DEFAULT_ROLE] =
679 CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
680 9736 sql_command_flags[SQLCOM_GRANT_ROLE] =
681 CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
682 9736 sql_command_flags[SQLCOM_REVOKE_ROLE] =
683 CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
684 9736 sql_command_flags[SQLCOM_DROP_ROLE] =
685 CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
686 9736 sql_command_flags[SQLCOM_CREATE_ROLE] =
687 CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
688
689 9736 sql_command_flags[SQLCOM_OPTIMIZE] = CF_CHANGES_DATA;
690 9736 sql_command_flags[SQLCOM_ALTER_INSTANCE] = CF_CHANGES_DATA;
691 9736 sql_command_flags[SQLCOM_CREATE_FUNCTION] =
692 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
693 9736 sql_command_flags[SQLCOM_CREATE_PROCEDURE] =
694 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
695 9736 sql_command_flags[SQLCOM_CREATE_SPFUNCTION] =
696 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
697 9736 sql_command_flags[SQLCOM_DROP_PROCEDURE] =
698 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
699 9736 sql_command_flags[SQLCOM_DROP_FUNCTION] =
700 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
701 9736 sql_command_flags[SQLCOM_ALTER_PROCEDURE] =
702 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
703 9736 sql_command_flags[SQLCOM_ALTER_FUNCTION] =
704 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
705 9736 sql_command_flags[SQLCOM_INSTALL_PLUGIN] =
706 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
707 9736 sql_command_flags[SQLCOM_UNINSTALL_PLUGIN] =
708 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
709 9736 sql_command_flags[SQLCOM_INSTALL_COMPONENT] =
710 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
711 9736 sql_command_flags[SQLCOM_UNINSTALL_COMPONENT] =
712 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
713 9736 sql_command_flags[SQLCOM_CREATE_RESOURCE_GROUP] =
714 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_ALLOW_PROTOCOL_PLUGIN;
715 9736 sql_command_flags[SQLCOM_ALTER_RESOURCE_GROUP] =
716 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_ALLOW_PROTOCOL_PLUGIN;
717 9736 sql_command_flags[SQLCOM_DROP_RESOURCE_GROUP] =
718 CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_ALLOW_PROTOCOL_PLUGIN;
719 9736 sql_command_flags[SQLCOM_SET_RESOURCE_GROUP] =
720 CF_CHANGES_DATA | CF_ALLOW_PROTOCOL_PLUGIN;
721
722 9736 sql_command_flags[SQLCOM_CLONE] =
723 CF_AUTO_COMMIT_TRANS | CF_ALLOW_PROTOCOL_PLUGIN;
724
725 /* Does not change the contents of the Diagnostics Area. */
726 9736 sql_command_flags[SQLCOM_GET_DIAGNOSTICS] = CF_DIAGNOSTIC_STMT;
727
728 /*
729 (1): without it, in "CALL some_proc((subq))", subquery would not be
730 traced.
731 */
732 9736 sql_command_flags[SQLCOM_CALL] = CF_REEXECUTION_FRAGILE |
733 CF_CAN_GENERATE_ROW_EVENTS |
734 CF_OPTIMIZER_TRACE; // (1)
735 9736 sql_command_flags[SQLCOM_EXECUTE] = CF_CAN_GENERATE_ROW_EVENTS;
736
737 /*
738 The following admin table operations are allowed
739 on log tables.
740 */
741 9736 sql_command_flags[SQLCOM_REPAIR] =
742 CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS;
743 9736 sql_command_flags[SQLCOM_OPTIMIZE] |=
744 CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS;
745 9736 sql_command_flags[SQLCOM_ANALYZE] =
746 CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS;
747 9736 sql_command_flags[SQLCOM_CHECK] =
748 CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS;
749
750 9736 sql_command_flags[SQLCOM_CREATE_USER] |= CF_AUTO_COMMIT_TRANS;
751 9736 sql_command_flags[SQLCOM_CREATE_ROLE] |= CF_AUTO_COMMIT_TRANS;
752 9736 sql_command_flags[SQLCOM_DROP_USER] |= CF_AUTO_COMMIT_TRANS;
753 9736 sql_command_flags[SQLCOM_DROP_ROLE] |= CF_AUTO_COMMIT_TRANS;
754 9736 sql_command_flags[SQLCOM_RENAME_USER] |= CF_AUTO_COMMIT_TRANS;
755 9736 sql_command_flags[SQLCOM_ALTER_USER] |= CF_AUTO_COMMIT_TRANS;
756 9736 sql_command_flags[SQLCOM_RESTART_SERVER] =
757 CF_AUTO_COMMIT_TRANS | CF_ALLOW_PROTOCOL_PLUGIN;
758 9736 sql_command_flags[SQLCOM_REVOKE] |= CF_AUTO_COMMIT_TRANS;
759 9736 sql_command_flags[SQLCOM_REVOKE_ALL] |= CF_AUTO_COMMIT_TRANS;
760 9736 sql_command_flags[SQLCOM_REVOKE_ROLE] |= CF_AUTO_COMMIT_TRANS;
761 9736 sql_command_flags[SQLCOM_GRANT] |= CF_AUTO_COMMIT_TRANS;
762 9736 sql_command_flags[SQLCOM_GRANT_ROLE] |= CF_AUTO_COMMIT_TRANS;
763 9736 sql_command_flags[SQLCOM_ALTER_USER_DEFAULT_ROLE] |= CF_AUTO_COMMIT_TRANS;
764
765 9736 sql_command_flags[SQLCOM_ASSIGN_TO_KEYCACHE] = CF_AUTO_COMMIT_TRANS;
766 9736 sql_command_flags[SQLCOM_PRELOAD_KEYS] = CF_AUTO_COMMIT_TRANS;
767 9736 sql_command_flags[SQLCOM_ALTER_INSTANCE] |= CF_AUTO_COMMIT_TRANS;
768
769 9736 sql_command_flags[SQLCOM_FLUSH] = CF_AUTO_COMMIT_TRANS;
770 9736 sql_command_flags[SQLCOM_RESET] = CF_AUTO_COMMIT_TRANS;
771 9736 sql_command_flags[SQLCOM_CREATE_SERVER] = CF_AUTO_COMMIT_TRANS;
772 9736 sql_command_flags[SQLCOM_ALTER_SERVER] = CF_AUTO_COMMIT_TRANS;
773 9736 sql_command_flags[SQLCOM_DROP_SERVER] = CF_AUTO_COMMIT_TRANS;
774 9736 sql_command_flags[SQLCOM_CHANGE_MASTER] = CF_AUTO_COMMIT_TRANS;
775 9736 sql_command_flags[SQLCOM_CHANGE_REPLICATION_FILTER] = CF_AUTO_COMMIT_TRANS;
776 9736 sql_command_flags[SQLCOM_SLAVE_START] = CF_AUTO_COMMIT_TRANS;
777 9736 sql_command_flags[SQLCOM_SLAVE_STOP] = CF_AUTO_COMMIT_TRANS;
778 9736 sql_command_flags[SQLCOM_STOP_GROUP_REPLICATION] = CF_IMPLICIT_COMMIT_END;
779 9736 sql_command_flags[SQLCOM_ALTER_TABLESPACE] |= CF_AUTO_COMMIT_TRANS;
780 9736 sql_command_flags[SQLCOM_CREATE_SRS] |= CF_AUTO_COMMIT_TRANS;
781 9736 sql_command_flags[SQLCOM_DROP_SRS] |= CF_AUTO_COMMIT_TRANS;
782
783 /*
784 The following statements can deal with temporary tables,
785 so temporary tables should be pre-opened for those statements to
786 simplify privilege checking.
787
788 There are other statements that deal with temporary tables and open
789 them, but which are not listed here. The thing is that the order of
790 pre-opening temporary tables for those statements is somewhat custom.
791 */
792 9736 sql_command_flags[SQLCOM_CREATE_TABLE] |= CF_PREOPEN_TMP_TABLES;
793 9736 sql_command_flags[SQLCOM_DROP_TABLE] |= CF_PREOPEN_TMP_TABLES;
794 9736 sql_command_flags[SQLCOM_CREATE_INDEX] |= CF_PREOPEN_TMP_TABLES;
795 9736 sql_command_flags[SQLCOM_ALTER_TABLE] |= CF_PREOPEN_TMP_TABLES;
796 9736 sql_command_flags[SQLCOM_TRUNCATE] |= CF_PREOPEN_TMP_TABLES;
797 9736 sql_command_flags[SQLCOM_LOAD] |= CF_PREOPEN_TMP_TABLES;
798 9736 sql_command_flags[SQLCOM_DROP_INDEX] |= CF_PREOPEN_TMP_TABLES;
799 9736 sql_command_flags[SQLCOM_UPDATE] |= CF_PREOPEN_TMP_TABLES;
800 9736 sql_command_flags[SQLCOM_UPDATE_MULTI] |= CF_PREOPEN_TMP_TABLES;
801 9736 sql_command_flags[SQLCOM_INSERT] |= CF_PREOPEN_TMP_TABLES;
802 9736 sql_command_flags[SQLCOM_INSERT_SELECT] |= CF_PREOPEN_TMP_TABLES;
803 9736 sql_command_flags[SQLCOM_DELETE] |= CF_PREOPEN_TMP_TABLES;
804 9736 sql_command_flags[SQLCOM_DELETE_MULTI] |= CF_PREOPEN_TMP_TABLES;
805 9736 sql_command_flags[SQLCOM_REPLACE] |= CF_PREOPEN_TMP_TABLES;
806 9736 sql_command_flags[SQLCOM_REPLACE_SELECT] |= CF_PREOPEN_TMP_TABLES;
807 9736 sql_command_flags[SQLCOM_SELECT] |= CF_PREOPEN_TMP_TABLES;
808 9736 sql_command_flags[SQLCOM_SET_OPTION] |= CF_PREOPEN_TMP_TABLES;
809 9736 sql_command_flags[SQLCOM_DO] |= CF_PREOPEN_TMP_TABLES;
810 9736 sql_command_flags[SQLCOM_CALL] |= CF_PREOPEN_TMP_TABLES;
811 9736 sql_command_flags[SQLCOM_CHECKSUM] |= CF_PREOPEN_TMP_TABLES;
812 9736 sql_command_flags[SQLCOM_ANALYZE] |= CF_PREOPEN_TMP_TABLES;
813 9736 sql_command_flags[SQLCOM_CHECK] |= CF_PREOPEN_TMP_TABLES;
814 9736 sql_command_flags[SQLCOM_OPTIMIZE] |= CF_PREOPEN_TMP_TABLES;
815 9736 sql_command_flags[SQLCOM_REPAIR] |= CF_PREOPEN_TMP_TABLES;
816 9736 sql_command_flags[SQLCOM_PRELOAD_KEYS] |= CF_PREOPEN_TMP_TABLES;
817 9736 sql_command_flags[SQLCOM_ASSIGN_TO_KEYCACHE] |= CF_PREOPEN_TMP_TABLES;
818
819 /*
820 DDL statements that should start with closing opened handlers.
821
822 We use this flag only for statements for which open HANDLERs
823 have to be closed before emporary tables are pre-opened.
824 */
825 9736 sql_command_flags[SQLCOM_CREATE_TABLE] |= CF_HA_CLOSE;
826 9736 sql_command_flags[SQLCOM_DROP_TABLE] |= CF_HA_CLOSE;
827 9736 sql_command_flags[SQLCOM_ALTER_TABLE] |= CF_HA_CLOSE;
828 9736 sql_command_flags[SQLCOM_TRUNCATE] |= CF_HA_CLOSE;
829 9736 sql_command_flags[SQLCOM_REPAIR] |= CF_HA_CLOSE;
830 9736 sql_command_flags[SQLCOM_OPTIMIZE] |= CF_HA_CLOSE;
831 9736 sql_command_flags[SQLCOM_ANALYZE] |= CF_HA_CLOSE;
832 9736 sql_command_flags[SQLCOM_CHECK] |= CF_HA_CLOSE;
833 9736 sql_command_flags[SQLCOM_CREATE_INDEX] |= CF_HA_CLOSE;
834 9736 sql_command_flags[SQLCOM_DROP_INDEX] |= CF_HA_CLOSE;
835 9736 sql_command_flags[SQLCOM_PRELOAD_KEYS] |= CF_HA_CLOSE;
836 9736 sql_command_flags[SQLCOM_ASSIGN_TO_KEYCACHE] |= CF_HA_CLOSE;
837
838 /*
839 Mark statements that always are disallowed in read-only
840 transactions. Note that according to the SQL standard,
841 even temporary table DDL should be disallowed.
842 */
843 9736 sql_command_flags[SQLCOM_CREATE_TABLE] |= CF_DISALLOW_IN_RO_TRANS;
844 9736 sql_command_flags[SQLCOM_ALTER_TABLE] |= CF_DISALLOW_IN_RO_TRANS;
845 9736 sql_command_flags[SQLCOM_DROP_TABLE] |= CF_DISALLOW_IN_RO_TRANS;
846 9736 sql_command_flags[SQLCOM_RENAME_TABLE] |= CF_DISALLOW_IN_RO_TRANS;
847 9736 sql_command_flags[SQLCOM_CREATE_INDEX] |= CF_DISALLOW_IN_RO_TRANS;
848 9736 sql_command_flags[SQLCOM_DROP_INDEX] |= CF_DISALLOW_IN_RO_TRANS;
849 9736 sql_command_flags[SQLCOM_CREATE_DB] |= CF_DISALLOW_IN_RO_TRANS;
850 9736 sql_command_flags[SQLCOM_DROP_DB] |= CF_DISALLOW_IN_RO_TRANS;
851 9736 sql_command_flags[SQLCOM_ALTER_DB] |= CF_DISALLOW_IN_RO_TRANS;
852 9736 sql_command_flags[SQLCOM_CREATE_VIEW] |= CF_DISALLOW_IN_RO_TRANS;
853 9736 sql_command_flags[SQLCOM_DROP_VIEW] |= CF_DISALLOW_IN_RO_TRANS;
854 9736 sql_command_flags[SQLCOM_CREATE_TRIGGER] |= CF_DISALLOW_IN_RO_TRANS;
855 9736 sql_command_flags[SQLCOM_DROP_TRIGGER] |= CF_DISALLOW_IN_RO_TRANS;
856 9736 sql_command_flags[SQLCOM_CREATE_EVENT] |= CF_DISALLOW_IN_RO_TRANS;
857 9736 sql_command_flags[SQLCOM_ALTER_EVENT] |= CF_DISALLOW_IN_RO_TRANS;
858 9736 sql_command_flags[SQLCOM_DROP_EVENT] |= CF_DISALLOW_IN_RO_TRANS;
859 9736 sql_command_flags[SQLCOM_CREATE_USER] |= CF_DISALLOW_IN_RO_TRANS;
860 9736 sql_command_flags[SQLCOM_CREATE_ROLE] |= CF_DISALLOW_IN_RO_TRANS;
861 9736 sql_command_flags[SQLCOM_RENAME_USER] |= CF_DISALLOW_IN_RO_TRANS;
862 9736 sql_command_flags[SQLCOM_ALTER_USER] |= CF_DISALLOW_IN_RO_TRANS;
863 9736 sql_command_flags[SQLCOM_DROP_USER] |= CF_DISALLOW_IN_RO_TRANS;
864 9736 sql_command_flags[SQLCOM_DROP_ROLE] |= CF_DISALLOW_IN_RO_TRANS;
865 9736 sql_command_flags[SQLCOM_CREATE_SERVER] |= CF_DISALLOW_IN_RO_TRANS;
866 9736 sql_command_flags[SQLCOM_ALTER_SERVER] |= CF_DISALLOW_IN_RO_TRANS;
867 9736 sql_command_flags[SQLCOM_DROP_SERVER] |= CF_DISALLOW_IN_RO_TRANS;
868 9736 sql_command_flags[SQLCOM_CREATE_FUNCTION] |= CF_DISALLOW_IN_RO_TRANS;
869 9736 sql_command_flags[SQLCOM_CREATE_PROCEDURE] |= CF_DISALLOW_IN_RO_TRANS;
870 9736 sql_command_flags[SQLCOM_CREATE_SPFUNCTION] |= CF_DISALLOW_IN_RO_TRANS;
871 9736 sql_command_flags[SQLCOM_DROP_PROCEDURE] |= CF_DISALLOW_IN_RO_TRANS;
872 9736 sql_command_flags[SQLCOM_DROP_FUNCTION] |= CF_DISALLOW_IN_RO_TRANS;
873 9736 sql_command_flags[SQLCOM_ALTER_PROCEDURE] |= CF_DISALLOW_IN_RO_TRANS;
874 9736 sql_command_flags[SQLCOM_ALTER_FUNCTION] |= CF_DISALLOW_IN_RO_TRANS;
875 9736 sql_command_flags[SQLCOM_TRUNCATE] |= CF_DISALLOW_IN_RO_TRANS;
876 9736 sql_command_flags[SQLCOM_ALTER_TABLESPACE] |= CF_DISALLOW_IN_RO_TRANS;
877 9736 sql_command_flags[SQLCOM_REPAIR] |= CF_DISALLOW_IN_RO_TRANS;
878 9736 sql_command_flags[SQLCOM_OPTIMIZE] |= CF_DISALLOW_IN_RO_TRANS;
879 9736 sql_command_flags[SQLCOM_GRANT] |= CF_DISALLOW_IN_RO_TRANS;
880 9736 sql_command_flags[SQLCOM_GRANT_ROLE] |= CF_DISALLOW_IN_RO_TRANS;
881 9736 sql_command_flags[SQLCOM_REVOKE] |= CF_DISALLOW_IN_RO_TRANS;
882 9736 sql_command_flags[SQLCOM_REVOKE_ALL] |= CF_DISALLOW_IN_RO_TRANS;
883 9736 sql_command_flags[SQLCOM_REVOKE_ROLE] |= CF_DISALLOW_IN_RO_TRANS;
884 9736 sql_command_flags[SQLCOM_INSTALL_PLUGIN] |= CF_DISALLOW_IN_RO_TRANS;
885 9736 sql_command_flags[SQLCOM_UNINSTALL_PLUGIN] |= CF_DISALLOW_IN_RO_TRANS;
886 9736 sql_command_flags[SQLCOM_INSTALL_COMPONENT] |= CF_DISALLOW_IN_RO_TRANS;
887 9736 sql_command_flags[SQLCOM_UNINSTALL_COMPONENT] |= CF_DISALLOW_IN_RO_TRANS;
888 9736 sql_command_flags[SQLCOM_ALTER_INSTANCE] |= CF_DISALLOW_IN_RO_TRANS;
889 9736 sql_command_flags[SQLCOM_IMPORT] |= CF_DISALLOW_IN_RO_TRANS;
890 9736 sql_command_flags[SQLCOM_CREATE_SRS] |= CF_DISALLOW_IN_RO_TRANS;
891 9736 sql_command_flags[SQLCOM_DROP_SRS] |= CF_DISALLOW_IN_RO_TRANS;
892 9736 sql_command_flags[SQLCOM_CREATE_COMPRESSION_DICTIONARY] |=
893 CF_DISALLOW_IN_RO_TRANS;
894 9736 sql_command_flags[SQLCOM_DROP_COMPRESSION_DICTIONARY] |=
895 CF_DISALLOW_IN_RO_TRANS;
896
897 /*
898 Mark statements that are allowed to be executed by the plugins.
899 */
900 9736 sql_command_flags[SQLCOM_SELECT] |= CF_ALLOW_PROTOCOL_PLUGIN;
901 9736 sql_command_flags[SQLCOM_CREATE_TABLE] |= CF_ALLOW_PROTOCOL_PLUGIN;
902 9736 sql_command_flags[SQLCOM_CREATE_INDEX] |= CF_ALLOW_PROTOCOL_PLUGIN;
903 9736 sql_command_flags[SQLCOM_ALTER_TABLE] |= CF_ALLOW_PROTOCOL_PLUGIN;
904 9736 sql_command_flags[SQLCOM_UPDATE] |= CF_ALLOW_PROTOCOL_PLUGIN;
905 9736 sql_command_flags[SQLCOM_INSERT] |= CF_ALLOW_PROTOCOL_PLUGIN;
906 9736 sql_command_flags[SQLCOM_INSERT_SELECT] |= CF_ALLOW_PROTOCOL_PLUGIN;
907 9736 sql_command_flags[SQLCOM_DELETE] |= CF_ALLOW_PROTOCOL_PLUGIN;
908 9736 sql_command_flags[SQLCOM_TRUNCATE] |= CF_ALLOW_PROTOCOL_PLUGIN;
909 9736 sql_command_flags[SQLCOM_DROP_TABLE] |= CF_ALLOW_PROTOCOL_PLUGIN;
910 9736 sql_command_flags[SQLCOM_DROP_INDEX] |= CF_ALLOW_PROTOCOL_PLUGIN;
911 9736 sql_command_flags[SQLCOM_SHOW_DATABASES] |= CF_ALLOW_PROTOCOL_PLUGIN;
912 9736 sql_command_flags[SQLCOM_SHOW_TABLES] |= CF_ALLOW_PROTOCOL_PLUGIN;
913 9736 sql_command_flags[SQLCOM_SHOW_FIELDS] |= CF_ALLOW_PROTOCOL_PLUGIN;
914 9736 sql_command_flags[SQLCOM_SHOW_KEYS] |= CF_ALLOW_PROTOCOL_PLUGIN;
915 9736 sql_command_flags[SQLCOM_SHOW_VARIABLES] |= CF_ALLOW_PROTOCOL_PLUGIN;
916 9736 sql_command_flags[SQLCOM_SHOW_STATUS] |= CF_ALLOW_PROTOCOL_PLUGIN;
917 9736 sql_command_flags[SQLCOM_SHOW_ENGINE_LOGS] |= CF_ALLOW_PROTOCOL_PLUGIN;
918 9736 sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS] |= CF_ALLOW_PROTOCOL_PLUGIN;
919 9736 sql_command_flags[SQLCOM_SHOW_ENGINE_MUTEX] |= CF_ALLOW_PROTOCOL_PLUGIN;
920 9736 sql_command_flags[SQLCOM_SHOW_PROCESSLIST] |= CF_ALLOW_PROTOCOL_PLUGIN;
921 9736 sql_command_flags[SQLCOM_SHOW_MASTER_STAT] |= CF_ALLOW_PROTOCOL_PLUGIN;
922 9736 sql_command_flags[SQLCOM_SHOW_SLAVE_STAT] |= CF_ALLOW_PROTOCOL_PLUGIN;
923 9736 sql_command_flags[SQLCOM_SHOW_GRANTS] |= CF_ALLOW_PROTOCOL_PLUGIN;
924 9736 sql_command_flags[SQLCOM_SHOW_CREATE] |= CF_ALLOW_PROTOCOL_PLUGIN;
925 9736 sql_command_flags[SQLCOM_SHOW_CHARSETS] |= CF_ALLOW_PROTOCOL_PLUGIN;
926 9736 sql_command_flags[SQLCOM_SHOW_COLLATIONS] |= CF_ALLOW_PROTOCOL_PLUGIN;
927 9736 sql_command_flags[SQLCOM_SHOW_CREATE_DB] |= CF_ALLOW_PROTOCOL_PLUGIN;
928 9736 sql_command_flags[SQLCOM_SHOW_TABLE_STATUS] |= CF_ALLOW_PROTOCOL_PLUGIN;
929 9736 sql_command_flags[SQLCOM_SHOW_TRIGGERS] |= CF_ALLOW_PROTOCOL_PLUGIN;
930 9736 sql_command_flags[SQLCOM_LOAD] |= CF_ALLOW_PROTOCOL_PLUGIN;
931 9736 sql_command_flags[SQLCOM_SET_OPTION] |= CF_ALLOW_PROTOCOL_PLUGIN;
932 9736 sql_command_flags[SQLCOM_LOCK_TABLES] |= CF_ALLOW_PROTOCOL_PLUGIN;
933 9736 sql_command_flags[SQLCOM_UNLOCK_TABLES] |= CF_ALLOW_PROTOCOL_PLUGIN;
934 9736 sql_command_flags[SQLCOM_GRANT] |= CF_ALLOW_PROTOCOL_PLUGIN;
935 9736 sql_command_flags[SQLCOM_CHANGE_DB] |= CF_ALLOW_PROTOCOL_PLUGIN;
936 9736 sql_command_flags[SQLCOM_CREATE_DB] |= CF_ALLOW_PROTOCOL_PLUGIN;
937 9736 sql_command_flags[SQLCOM_DROP_DB] |= CF_ALLOW_PROTOCOL_PLUGIN;
938 9736 sql_command_flags[SQLCOM_ALTER_DB] |= CF_ALLOW_PROTOCOL_PLUGIN;
939 9736 sql_command_flags[SQLCOM_REPAIR] |= CF_ALLOW_PROTOCOL_PLUGIN;
940 9736 sql_command_flags[SQLCOM_REPLACE] |= CF_ALLOW_PROTOCOL_PLUGIN;
941 9736 sql_command_flags[SQLCOM_REPLACE_SELECT] |= CF_ALLOW_PROTOCOL_PLUGIN;
942 9736 sql_command_flags[SQLCOM_CREATE_FUNCTION] |= CF_ALLOW_PROTOCOL_PLUGIN;
943 9736 sql_command_flags[SQLCOM_DROP_FUNCTION] |= CF_ALLOW_PROTOCOL_PLUGIN;
944 9736 sql_command_flags[SQLCOM_REVOKE] |= CF_ALLOW_PROTOCOL_PLUGIN;
945 9736 sql_command_flags[SQLCOM_OPTIMIZE] |= CF_ALLOW_PROTOCOL_PLUGIN;
946 9736 sql_command_flags[SQLCOM_CHECK] |= CF_ALLOW_PROTOCOL_PLUGIN;
947 9736 sql_command_flags[SQLCOM_ASSIGN_TO_KEYCACHE] |= CF_ALLOW_PROTOCOL_PLUGIN;
948 9736 sql_command_flags[SQLCOM_PRELOAD_KEYS] |= CF_ALLOW_PROTOCOL_PLUGIN;
949 9736 sql_command_flags[SQLCOM_FLUSH] |= CF_ALLOW_PROTOCOL_PLUGIN;
950 9736 sql_command_flags[SQLCOM_KILL] |= CF_ALLOW_PROTOCOL_PLUGIN;
951 9736 sql_command_flags[SQLCOM_ANALYZE] |= CF_ALLOW_PROTOCOL_PLUGIN;
952 9736 sql_command_flags[SQLCOM_ROLLBACK] |= CF_ALLOW_PROTOCOL_PLUGIN;
953 9736 sql_command_flags[SQLCOM_ROLLBACK_TO_SAVEPOINT] |= CF_ALLOW_PROTOCOL_PLUGIN;
954 9736 sql_command_flags[SQLCOM_COMMIT] |= CF_ALLOW_PROTOCOL_PLUGIN;
955 9736 sql_command_flags[SQLCOM_SAVEPOINT] |= CF_ALLOW_PROTOCOL_PLUGIN;
956 9736 sql_command_flags[SQLCOM_RELEASE_SAVEPOINT] |= CF_ALLOW_PROTOCOL_PLUGIN;
957 9736 sql_command_flags[SQLCOM_SLAVE_START] |= CF_ALLOW_PROTOCOL_PLUGIN;
958 9736 sql_command_flags[SQLCOM_SLAVE_STOP] |= CF_ALLOW_PROTOCOL_PLUGIN;
959 9736 sql_command_flags[SQLCOM_START_GROUP_REPLICATION] |= CF_ALLOW_PROTOCOL_PLUGIN;
960 9736 sql_command_flags[SQLCOM_STOP_GROUP_REPLICATION] |= CF_ALLOW_PROTOCOL_PLUGIN;
961 9736 sql_command_flags[SQLCOM_BEGIN] |= CF_ALLOW_PROTOCOL_PLUGIN;
962 9736 sql_command_flags[SQLCOM_CHANGE_MASTER] |= CF_ALLOW_PROTOCOL_PLUGIN;
963 9736 sql_command_flags[SQLCOM_CHANGE_REPLICATION_FILTER] |=
964 CF_ALLOW_PROTOCOL_PLUGIN;
965 9736 sql_command_flags[SQLCOM_RENAME_TABLE] |= CF_ALLOW_PROTOCOL_PLUGIN;
966 9736 sql_command_flags[SQLCOM_RESET] |= CF_ALLOW_PROTOCOL_PLUGIN;
967 9736 sql_command_flags[SQLCOM_PURGE] |= CF_ALLOW_PROTOCOL_PLUGIN;
968 9736 sql_command_flags[SQLCOM_PURGE_BEFORE] |= CF_ALLOW_PROTOCOL_PLUGIN;
969 9736 sql_command_flags[SQLCOM_SHOW_BINLOGS] |= CF_ALLOW_PROTOCOL_PLUGIN;
970 9736 sql_command_flags[SQLCOM_SHOW_OPEN_TABLES] |= CF_ALLOW_PROTOCOL_PLUGIN;
971 9736 sql_command_flags[SQLCOM_HA_OPEN] |= CF_ALLOW_PROTOCOL_PLUGIN;
972 9736 sql_command_flags[SQLCOM_HA_CLOSE] |= CF_ALLOW_PROTOCOL_PLUGIN;
973 9736 sql_command_flags[SQLCOM_HA_READ] |= CF_ALLOW_PROTOCOL_PLUGIN;
974 9736 sql_command_flags[SQLCOM_SHOW_SLAVE_HOSTS] |= CF_ALLOW_PROTOCOL_PLUGIN;
975 9736 sql_command_flags[SQLCOM_DELETE_MULTI] |= CF_ALLOW_PROTOCOL_PLUGIN;
976 9736 sql_command_flags[SQLCOM_UPDATE_MULTI] |= CF_ALLOW_PROTOCOL_PLUGIN;
977 9736 sql_command_flags[SQLCOM_SHOW_BINLOG_EVENTS] |= CF_ALLOW_PROTOCOL_PLUGIN;
978 9736 sql_command_flags[SQLCOM_DO] |= CF_ALLOW_PROTOCOL_PLUGIN;
979 9736 sql_command_flags[SQLCOM_SHOW_WARNS] |= CF_ALLOW_PROTOCOL_PLUGIN;
980 9736 sql_command_flags[SQLCOM_EMPTY_QUERY] |= CF_ALLOW_PROTOCOL_PLUGIN;
981 9736 sql_command_flags[SQLCOM_SHOW_ERRORS] |= CF_ALLOW_PROTOCOL_PLUGIN;
982 9736 sql_command_flags[SQLCOM_SHOW_STORAGE_ENGINES] |= CF_ALLOW_PROTOCOL_PLUGIN;
983 9736 sql_command_flags[SQLCOM_SHOW_PRIVILEGES] |= CF_ALLOW_PROTOCOL_PLUGIN;
984 9736 sql_command_flags[SQLCOM_HELP] |= CF_ALLOW_PROTOCOL_PLUGIN;
985 9736 sql_command_flags[SQLCOM_CREATE_USER] |= CF_ALLOW_PROTOCOL_PLUGIN;
986 9736 sql_command_flags[SQLCOM_DROP_USER] |= CF_ALLOW_PROTOCOL_PLUGIN;
987 9736 sql_command_flags[SQLCOM_RENAME_USER] |= CF_ALLOW_PROTOCOL_PLUGIN;
988 9736 sql_command_flags[SQLCOM_REVOKE_ALL] |= CF_ALLOW_PROTOCOL_PLUGIN;
989 9736 sql_command_flags[SQLCOM_CHECKSUM] |= CF_ALLOW_PROTOCOL_PLUGIN;
990 9736 sql_command_flags[SQLCOM_CREATE_PROCEDURE] |= CF_ALLOW_PROTOCOL_PLUGIN;
991 9736 sql_command_flags[SQLCOM_CREATE_SPFUNCTION] |= CF_ALLOW_PROTOCOL_PLUGIN;
992 9736 sql_command_flags[SQLCOM_CALL] |= CF_ALLOW_PROTOCOL_PLUGIN;
993 9736 sql_command_flags[SQLCOM_DROP_PROCEDURE] |= CF_ALLOW_PROTOCOL_PLUGIN;
994 9736 sql_command_flags[SQLCOM_ALTER_PROCEDURE] |= CF_ALLOW_PROTOCOL_PLUGIN;
995 9736 sql_command_flags[SQLCOM_ALTER_FUNCTION] |= CF_ALLOW_PROTOCOL_PLUGIN;
996 9736 sql_command_flags[SQLCOM_SHOW_CREATE_PROC] |= CF_ALLOW_PROTOCOL_PLUGIN;
997 9736 sql_command_flags[SQLCOM_SHOW_CREATE_FUNC] |= CF_ALLOW_PROTOCOL_PLUGIN;
998 9736 sql_command_flags[SQLCOM_SHOW_STATUS_PROC] |= CF_ALLOW_PROTOCOL_PLUGIN;
999 9736 sql_command_flags[SQLCOM_SHOW_STATUS_FUNC] |= CF_ALLOW_PROTOCOL_PLUGIN;
1000 9736 sql_command_flags[SQLCOM_PREPARE] |= CF_ALLOW_PROTOCOL_PLUGIN;
1001 9736 sql_command_flags[SQLCOM_EXECUTE] |= CF_ALLOW_PROTOCOL_PLUGIN;
1002 9736 sql_command_flags[SQLCOM_DEALLOCATE_PREPARE] |= CF_ALLOW_PROTOCOL_PLUGIN;
1003 9736 sql_command_flags[SQLCOM_CREATE_VIEW] |= CF_ALLOW_PROTOCOL_PLUGIN;
1004 9736 sql_command_flags[SQLCOM_DROP_VIEW] |= CF_ALLOW_PROTOCOL_PLUGIN;
1005 9736 sql_command_flags[SQLCOM_CREATE_TRIGGER] |= CF_ALLOW_PROTOCOL_PLUGIN;
1006 9736 sql_command_flags[SQLCOM_DROP_TRIGGER] |= CF_ALLOW_PROTOCOL_PLUGIN;
1007 9736 sql_command_flags[SQLCOM_XA_START] |= CF_ALLOW_PROTOCOL_PLUGIN;
1008 9736 sql_command_flags[SQLCOM_XA_END] |= CF_ALLOW_PROTOCOL_PLUGIN;
1009 9736 sql_command_flags[SQLCOM_XA_PREPARE] |= CF_ALLOW_PROTOCOL_PLUGIN;
1010 9736 sql_command_flags[SQLCOM_XA_COMMIT] |= CF_ALLOW_PROTOCOL_PLUGIN;
1011 9736 sql_command_flags[SQLCOM_XA_ROLLBACK] |= CF_ALLOW_PROTOCOL_PLUGIN;
1012 9736 sql_command_flags[SQLCOM_XA_RECOVER] |= CF_ALLOW_PROTOCOL_PLUGIN;
1013 9736 sql_command_flags[SQLCOM_SHOW_PROC_CODE] |= CF_ALLOW_PROTOCOL_PLUGIN;
1014 9736 sql_command_flags[SQLCOM_SHOW_FUNC_CODE] |= CF_ALLOW_PROTOCOL_PLUGIN;
1015 9736 sql_command_flags[SQLCOM_ALTER_TABLESPACE] |= CF_ALLOW_PROTOCOL_PLUGIN;
1016 9736 sql_command_flags[SQLCOM_BINLOG_BASE64_EVENT] |= CF_ALLOW_PROTOCOL_PLUGIN;
1017 9736 sql_command_flags[SQLCOM_SHOW_PLUGINS] |= CF_ALLOW_PROTOCOL_PLUGIN;
1018 9736 sql_command_flags[SQLCOM_CREATE_SERVER] |= CF_ALLOW_PROTOCOL_PLUGIN;
1019 9736 sql_command_flags[SQLCOM_DROP_SERVER] |= CF_ALLOW_PROTOCOL_PLUGIN;
1020 9736 sql_command_flags[SQLCOM_ALTER_SERVER] |= CF_ALLOW_PROTOCOL_PLUGIN;
1021 9736 sql_command_flags[SQLCOM_CREATE_EVENT] |= CF_ALLOW_PROTOCOL_PLUGIN;
1022 9736 sql_command_flags[SQLCOM_ALTER_EVENT] |= CF_ALLOW_PROTOCOL_PLUGIN;
1023 9736 sql_command_flags[SQLCOM_DROP_EVENT] |= CF_ALLOW_PROTOCOL_PLUGIN;
1024 9736 sql_command_flags[SQLCOM_SHOW_CREATE_EVENT] |= CF_ALLOW_PROTOCOL_PLUGIN;
1025 9736 sql_command_flags[SQLCOM_SHOW_EVENTS] |= CF_ALLOW_PROTOCOL_PLUGIN;
1026 9736 sql_command_flags[SQLCOM_SHOW_CREATE_TRIGGER] |= CF_ALLOW_PROTOCOL_PLUGIN;
1027 9736 sql_command_flags[SQLCOM_SHOW_PROFILE] |= CF_ALLOW_PROTOCOL_PLUGIN;
1028 9736 sql_command_flags[SQLCOM_SHOW_PROFILES] |= CF_ALLOW_PROTOCOL_PLUGIN;
1029 9736 sql_command_flags[SQLCOM_SIGNAL] |= CF_ALLOW_PROTOCOL_PLUGIN;
1030 9736 sql_command_flags[SQLCOM_RESIGNAL] |= CF_ALLOW_PROTOCOL_PLUGIN;
1031 9736 sql_command_flags[SQLCOM_SHOW_RELAYLOG_EVENTS] |= CF_ALLOW_PROTOCOL_PLUGIN;
1032 9736 sql_command_flags[SQLCOM_GET_DIAGNOSTICS] |= CF_ALLOW_PROTOCOL_PLUGIN;
1033 9736 sql_command_flags[SQLCOM_ALTER_USER] |= CF_ALLOW_PROTOCOL_PLUGIN;
1034 9736 sql_command_flags[SQLCOM_EXPLAIN_OTHER] |= CF_ALLOW_PROTOCOL_PLUGIN;
1035 9736 sql_command_flags[SQLCOM_SHOW_CREATE_USER] |= CF_ALLOW_PROTOCOL_PLUGIN;
1036 9736 sql_command_flags[SQLCOM_SET_PASSWORD] |= CF_ALLOW_PROTOCOL_PLUGIN;
1037 9736 sql_command_flags[SQLCOM_DROP_ROLE] |= CF_ALLOW_PROTOCOL_PLUGIN;
1038 9736 sql_command_flags[SQLCOM_CREATE_ROLE] |= CF_ALLOW_PROTOCOL_PLUGIN;
1039 9736 sql_command_flags[SQLCOM_SET_ROLE] |= CF_ALLOW_PROTOCOL_PLUGIN;
1040 9736 sql_command_flags[SQLCOM_GRANT_ROLE] |= CF_ALLOW_PROTOCOL_PLUGIN;
1041 9736 sql_command_flags[SQLCOM_REVOKE_ROLE] |= CF_ALLOW_PROTOCOL_PLUGIN;
1042 9736 sql_command_flags[SQLCOM_ALTER_USER_DEFAULT_ROLE] |= CF_ALLOW_PROTOCOL_PLUGIN;
1043 9736 sql_command_flags[SQLCOM_IMPORT] |= CF_ALLOW_PROTOCOL_PLUGIN;
1044 9736 sql_command_flags[SQLCOM_END] |= CF_ALLOW_PROTOCOL_PLUGIN;
1045 9736 sql_command_flags[SQLCOM_CREATE_SRS] |= CF_ALLOW_PROTOCOL_PLUGIN;
1046 9736 sql_command_flags[SQLCOM_DROP_SRS] |= CF_ALLOW_PROTOCOL_PLUGIN;
1047 9736 sql_command_flags[SQLCOM_SHOW_USER_STATS] |= CF_ALLOW_PROTOCOL_PLUGIN;
1048 9736 sql_command_flags[SQLCOM_SHOW_TABLE_STATS] |= CF_ALLOW_PROTOCOL_PLUGIN;
1049 9736 sql_command_flags[SQLCOM_SHOW_INDEX_STATS] |= CF_ALLOW_PROTOCOL_PLUGIN;
1050 9736 sql_command_flags[SQLCOM_SHOW_CLIENT_STATS] |= CF_ALLOW_PROTOCOL_PLUGIN;
1051 9736 sql_command_flags[SQLCOM_SHOW_THREAD_STATS] |= CF_ALLOW_PROTOCOL_PLUGIN;
1052
1053 /*
1054 Mark DDL statements which require that auto-commit mode to be temporarily
1055 turned off. See sqlcom_needs_autocommit_off() for more details.
1056
1057 CREATE TABLE and DROP TABLE are not marked as such as they have special
1058 variants dealing with temporary tables which don't update data-dictionary
1059 at all and which should be allowed in the middle of transaction.
1060 */
1061 9736 sql_command_flags[SQLCOM_CREATE_INDEX] |=
1062 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1063 9736 sql_command_flags[SQLCOM_ALTER_TABLE] |=
1064 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1065 9736 sql_command_flags[SQLCOM_TRUNCATE] |=
1066 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1067 9736 sql_command_flags[SQLCOM_DROP_INDEX] |=
1068 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1069 9736 sql_command_flags[SQLCOM_CREATE_DB] |=
1070 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1071 9736 sql_command_flags[SQLCOM_DROP_DB] |=
1072 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1073 9736 sql_command_flags[SQLCOM_ALTER_DB] |=
1074 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1075 9736 sql_command_flags[SQLCOM_REPAIR] |= CF_NEEDS_AUTOCOMMIT_OFF;
1076 9736 sql_command_flags[SQLCOM_OPTIMIZE] |= CF_NEEDS_AUTOCOMMIT_OFF;
1077 9736 sql_command_flags[SQLCOM_RENAME_TABLE] |=
1078 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1079 9736 sql_command_flags[SQLCOM_CREATE_VIEW] |=
1080 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1081 9736 sql_command_flags[SQLCOM_DROP_VIEW] |=
1082 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1083 9736 sql_command_flags[SQLCOM_ALTER_TABLESPACE] |=
1084 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1085 9736 sql_command_flags[SQLCOM_CREATE_SPFUNCTION] |=
1086 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1087 9736 sql_command_flags[SQLCOM_DROP_FUNCTION] |=
1088 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1089 9736 sql_command_flags[SQLCOM_ALTER_FUNCTION] |=
1090 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1091 9736 sql_command_flags[SQLCOM_CREATE_FUNCTION] |=
1092 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1093 9736 sql_command_flags[SQLCOM_CREATE_PROCEDURE] |=
1094 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1095 9736 sql_command_flags[SQLCOM_DROP_PROCEDURE] |=
1096 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1097 9736 sql_command_flags[SQLCOM_ALTER_PROCEDURE] |=
1098 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1099 9736 sql_command_flags[SQLCOM_CREATE_TRIGGER] |=
1100 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1101 9736 sql_command_flags[SQLCOM_DROP_TRIGGER] |=
1102 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1103 9736 sql_command_flags[SQLCOM_IMPORT] |=
1104 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1105 9736 sql_command_flags[SQLCOM_INSTALL_PLUGIN] |= CF_NEEDS_AUTOCOMMIT_OFF;
1106 9736 sql_command_flags[SQLCOM_UNINSTALL_PLUGIN] |= CF_NEEDS_AUTOCOMMIT_OFF;
1107 9736 sql_command_flags[SQLCOM_CREATE_EVENT] |=
1108 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1109 9736 sql_command_flags[SQLCOM_ALTER_EVENT] |=
1110 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1111 9736 sql_command_flags[SQLCOM_DROP_EVENT] |=
1112 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1113 9736 sql_command_flags[SQLCOM_CREATE_SRS] |=
1114 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1115 9736 sql_command_flags[SQLCOM_DROP_SRS] |=
1116 CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL;
1117
1118 /*
1119 Mark these statements as SHOW commands using INFORMATION_SCHEMA system
1120 views.
1121 */
1122 9736 sql_command_flags[SQLCOM_SHOW_CHARSETS] |= CF_SHOW_USES_SYSTEM_VIEW;
1123 9736 sql_command_flags[SQLCOM_SHOW_COLLATIONS] |= CF_SHOW_USES_SYSTEM_VIEW;
1124 9736 sql_command_flags[SQLCOM_SHOW_DATABASES] |= CF_SHOW_USES_SYSTEM_VIEW;
1125 9736 sql_command_flags[SQLCOM_SHOW_TABLES] |= CF_SHOW_USES_SYSTEM_VIEW;
1126 9736 sql_command_flags[SQLCOM_SHOW_TABLE_STATUS] |= CF_SHOW_USES_SYSTEM_VIEW;
1127 9736 sql_command_flags[SQLCOM_SHOW_FIELDS] |= CF_SHOW_USES_SYSTEM_VIEW;
1128 9736 sql_command_flags[SQLCOM_SHOW_KEYS] |= CF_SHOW_USES_SYSTEM_VIEW;
1129 9736 sql_command_flags[SQLCOM_SHOW_EVENTS] |= CF_SHOW_USES_SYSTEM_VIEW;
1130 9736 sql_command_flags[SQLCOM_SHOW_TRIGGERS] |= CF_SHOW_USES_SYSTEM_VIEW;
1131 9736 sql_command_flags[SQLCOM_SHOW_STATUS_PROC] |= CF_SHOW_USES_SYSTEM_VIEW;
1132 9736 sql_command_flags[SQLCOM_SHOW_STATUS_FUNC] |= CF_SHOW_USES_SYSTEM_VIEW;
1133
1134 /**
1135 Some statements doesn't if the ACL CACHE is disabled using the
1136 --skip-grant-tables server option.
1137 */
1138 9736 sql_command_flags[SQLCOM_SET_ROLE] |= CF_REQUIRE_ACL_CACHE;
1139 9736 sql_command_flags[SQLCOM_ALTER_USER_DEFAULT_ROLE] |= CF_REQUIRE_ACL_CACHE;
1140 9736 sql_command_flags[SQLCOM_CREATE_ROLE] |= CF_REQUIRE_ACL_CACHE;
1141 9736 sql_command_flags[SQLCOM_DROP_ROLE] |= CF_REQUIRE_ACL_CACHE;
1142 9736 sql_command_flags[SQLCOM_GRANT_ROLE] |= CF_REQUIRE_ACL_CACHE;
1143 9736 sql_command_flags[SQLCOM_ALTER_USER] |= CF_REQUIRE_ACL_CACHE;
1144 9736 sql_command_flags[SQLCOM_GRANT] |= CF_REQUIRE_ACL_CACHE;
1145 9736 sql_command_flags[SQLCOM_REVOKE] |= CF_REQUIRE_ACL_CACHE;
1146 9736 sql_command_flags[SQLCOM_REVOKE_ALL] |= CF_REQUIRE_ACL_CACHE;
1147 9736 sql_command_flags[SQLCOM_REVOKE_ROLE] |= CF_REQUIRE_ACL_CACHE;
1148 9736 sql_command_flags[SQLCOM_CREATE_USER] |= CF_REQUIRE_ACL_CACHE;
1149 9736 sql_command_flags[SQLCOM_DROP_USER] |= CF_REQUIRE_ACL_CACHE;
1150 9736 sql_command_flags[SQLCOM_RENAME_USER] |= CF_REQUIRE_ACL_CACHE;
1151 9736 sql_command_flags[SQLCOM_SHOW_GRANTS] |= CF_REQUIRE_ACL_CACHE;
1152 9736 sql_command_flags[SQLCOM_SET_PASSWORD] |= CF_REQUIRE_ACL_CACHE;
1153
1154 #ifdef WITH_WSREP
1155 /*
1156 Statements for which some errors are ignored when
1157 wsrep_ignore_apply_errors = WSREP_IGNORE_ERRORS_ON_RECONCILING_DDL
1158 */
1159 9736 sql_command_flags[SQLCOM_DROP_DB] |= CF_WSREP_MAY_IGNORE_ERRORS;
1160 9736 sql_command_flags[SQLCOM_DROP_TABLE] |= CF_WSREP_MAY_IGNORE_ERRORS;
1161 9736 sql_command_flags[SQLCOM_DROP_INDEX] |= CF_WSREP_MAY_IGNORE_ERRORS;
1162 9736 sql_command_flags[SQLCOM_ALTER_TABLE] |= CF_WSREP_MAY_IGNORE_ERRORS;
1163 #endif /* WITH_WSREP */
1164 9736 }
1165
1166 5612940 bool sqlcom_can_generate_row_events(enum enum_sql_command command) {
1167 5612940 return (sql_command_flags[command] & CF_CAN_GENERATE_ROW_EVENTS);
1168 }
1169
1170 6870162 bool is_update_query(enum enum_sql_command command) {
1171
2/4
✓ Branch 0 taken 6870334 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6870531 times.
✗ Branch 3 not taken.
6870162 assert(command >= 0 && command <= SQLCOM_END);
1172 6870531 return (sql_command_flags[command] & CF_CHANGES_DATA) != 0;
1173 }
1174
1175 21298250 bool is_explainable_query(enum enum_sql_command command) {
1176
3/4
✓ Branch 0 taken 21298418 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21298369 times.
✓ Branch 3 taken 49 times.
21298250 assert(command >= 0 && command <= SQLCOM_END);
1177 21298369 return (sql_command_flags[command] & CF_CAN_BE_EXPLAINED) != 0;
1178 }
1179
1180 /**
1181 Check if a sql command is allowed to write to log tables.
1182 @param command The SQL command
1183 @return true if writing is allowed
1184 */
1185 32522798 bool is_log_table_write_query(enum enum_sql_command command) {
1186
2/4
✓ Branch 0 taken 32522880 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32523000 times.
✗ Branch 3 not taken.
32522798 assert(command >= 0 && command <= SQLCOM_END);
1187 32523000 return (sql_command_flags[command] & CF_WRITE_LOGS_COMMAND) != 0;
1188 }
1189
1190 /**
1191 Check if statement (typically DDL) needs auto-commit mode temporarily
1192 turned off.
1193
1194 @note This is necessary to prevent InnoDB from automatically committing
1195 InnoDB transaction each time data-dictionary tables are closed
1196 after being updated.
1197 */
1198 21364332 static bool sqlcom_needs_autocommit_off(const LEX *lex) {
1199 42312595 return (sql_command_flags[lex->sql_command] & CF_NEEDS_AUTOCOMMIT_OFF) ||
1200
2/2
✓ Branch 0 taken 618837 times.
✓ Branch 1 taken 20329426 times.
20948263 (lex->sql_command == SQLCOM_CREATE_TABLE &&
1201
4/4
✓ Branch 0 taken 20948263 times.
✓ Branch 1 taken 416069 times.
✓ Branch 2 taken 47660 times.
✓ Branch 3 taken 571177 times.
42360255 !(lex->create_info->options & HA_LEX_CREATE_TMP_TABLE)) ||
1202
4/4
✓ Branch 0 taken 160736 times.
✓ Branch 1 taken 20216350 times.
✓ Branch 2 taken 153648 times.
✓ Branch 3 taken 7088 times.
41741418 (lex->sql_command == SQLCOM_DROP_TABLE && !lex->drop_temporary);
1203 }
1204
1205 33 void execute_init_command(THD *thd, LEX_STRING *init_command,
1206 mysql_rwlock_t *var_lock) {
1207
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 Protocol_classic *protocol = thd->get_protocol_classic();
1208 Vio *save_vio;
1209 ulong save_client_capabilities;
1210 COM_DATA com_data;
1211
1212
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 mysql_rwlock_rdlock(var_lock);
1213
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
33 if (!init_command->length) {
1214 mysql_rwlock_unlock(var_lock);
1215 return;
1216 }
1217
1218 /*
1219 copy the value under a lock, and release the lock.
1220 init_command has to be executed without a lock held,
1221 as it may try to change itself
1222 */
1223 33 size_t len = init_command->length;
1224
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 char *buf = thd->strmake(init_command->str, len);
1225
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 mysql_rwlock_unlock(var_lock);
1226
1227 #if defined(ENABLED_PROFILING)
1228
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 thd->profiling->start_new_query();
1229
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 thd->profiling->set_query_source(buf, len);
1230 #endif
1231
1232 /*
1233 Clear the DA in anticipation of possible failures in anticipation
1234 of possible command parsing failures.
1235 */
1236
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 thd->get_stmt_da()->reset_diagnostics_area();
1237
1238 /* For per-query performance counters with log_slow_statement */
1239 struct System_status_var query_start_status;
1240 33 thd->clear_copy_status_var();
1241
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
33 if (opt_log_slow_extra) {
1242 thd->copy_status_var(&query_start_status);
1243 }
1244
1245
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 THD_STAGE_INFO(thd, stage_execution_of_init_command);
1246
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 save_client_capabilities = protocol->get_client_capabilities();
1247 33 protocol->add_client_capability(CLIENT_MULTI_QUERIES);
1248 /*
1249 We do not prepare a COM_QUERY packet with query attributes
1250 since the init commands have nobody to supply query attributes.
1251 */
1252 33 protocol->remove_client_capability(CLIENT_QUERY_ATTRIBUTES);
1253 /*
1254 We don't need return result of execution to client side.
1255 To forbid this we should set thd->net.vio to 0.
1256 */
1257
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 save_vio = protocol->get_vio();
1258
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 protocol->set_vio(nullptr);
1259
2/4
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
33 if (!protocol->create_command(&com_data, COM_QUERY, (uchar *)buf, len))
1260
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 dispatch_command(thd, &com_data, COM_QUERY);
1261 33 protocol->set_client_capabilities(save_client_capabilities);
1262
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 protocol->set_vio(save_vio);
1263
1264 #if defined(ENABLED_PROFILING)
1265
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 thd->profiling->finish_current_query();
1266 #endif
1267 }
1268
1269 /* This works because items are allocated with (*THR_MALLOC)->Alloc() */
1270
1271 98708 void free_items(Item *item) {
1272 Item *next;
1273
1/2
✓ Branch 0 taken 98708 times.
✗ Branch 1 not taken.
98708 DBUG_TRACE;
1274
2/2
✓ Branch 0 taken 1006427 times.
✓ Branch 1 taken 98708 times.
1105135 for (; item; item = next) {
1275 1006427 next = item->next_free;
1276 1006427 item->delete_self();
1277 }
1278 98708 }
1279
1280 /**
1281 This works because items are allocated with (*THR_MALLOC)->Alloc().
1282 @note The function also handles null pointers (empty list).
1283 */
1284 50832566 void cleanup_items(Item *item) {
1285
1/2
✓ Branch 0 taken 50836030 times.
✗ Branch 1 not taken.
50832566 DBUG_TRACE;
1286
3/4
✓ Branch 0 taken 499072746 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 499081170 times.
✓ Branch 3 taken 50827606 times.
549908776 for (; item; item = item->next_free) item->cleanup();
1287 50827606 }
1288
1289 #ifdef WITH_WSREP
1290 1557 static bool wsrep_tables_accessible_when_detached(const TABLE_LIST *tables) {
1291 1557 bool has_tables = false;
1292
2/2
✓ Branch 0 taken 1325 times.
✓ Branch 1 taken 1209 times.
2534 for (const TABLE_LIST *table = tables; table; table = table->next_global) {
1293 TABLE_CATEGORY c;
1294 LEX_CSTRING db, tn;
1295
1296 /* PXC-2557 : skip if NULL, otherwise lex_string_set will crash */
1297
2/4
✓ Branch 0 taken 1325 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1325 times.
1325 if (!table->db || !table->table_name) continue;
1298
1299 1325 lex_cstring_set(&db, const_cast<char *>(table->db));
1300 1325 lex_cstring_set(&tn, const_cast<char *>(table->table_name));
1301
1/2
✓ Branch 0 taken 1325 times.
✗ Branch 1 not taken.
1325 c = get_table_category(db, tn);
1302
4/4
✓ Branch 0 taken 1319 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 348 times.
✓ Branch 3 taken 971 times.
1325 if (c != TABLE_CATEGORY_INFORMATION && c != TABLE_CATEGORY_PERFORMANCE) {
1303 348 return false;
1304 }
1305 977 has_tables = true;
1306 }
1307 1209 return has_tables;
1308 }
1309 #endif /* WITH_WSREP */
1310
1311 /**
1312 Bind Item fields to Field objects.
1313
1314 @param first Pointer to first item, follow "next" chain to visit all items
1315 */
1316 12697472 void bind_fields(Item *first) {
1317
2/2
✓ Branch 0 taken 148058964 times.
✓ Branch 1 taken 12696489 times.
160755453 for (Item *item = first; item; item = item->next_free) item->bind_fields();
1318 12696489 }
1319
1320 /**
1321 Checks if the period net_buffer_shrink_interval is over.
1322 */
1323 11085646 static bool net_buffer_shrink_interval_is_over(
1324 const THD *const thd, unsigned long long net_buffer_shrink_time) {
1325 // N.B. Make a copy to use the same variable during all the function
1326 // as it could be modified in another session.
1327 11085646 auto interval = net_buffer_shrink_interval;
1328
1329
2/2
✓ Branch 0 taken 486 times.
✓ Branch 1 taken 11085160 times.
11086132 return interval != 0 &&
1330
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 477 times.
11086132 thd->start_utime / 1000000 > net_buffer_shrink_time + interval;
1331 }
1332
1333 /**
1334 Shrinks the packet buffer if the max size during the last
1335 global.net_buffer_shrink_interval is smaller than the current size.
1336 */
1337 11084702 static bool shrink_packet_buffer(THD *thd, unsigned long *max_interval_packet,
1338 unsigned long long *net_buffer_shrink_time) {
1339
1/2
✓ Branch 0 taken 11085747 times.
✗ Branch 1 not taken.
11084702 if (!net_buffer_shrink_interval_is_over(thd, *net_buffer_shrink_time)) {
1340 11085747 return false;
1341 }
1342
1343 auto net = thd->get_protocol_classic()->get_net();
1344 9 auto was_shrunk = my_net_shrink_buffer(net, thd->variables.net_buffer_length,
1345 max_interval_packet);
1346 9 *net_buffer_shrink_time = thd->start_utime / 1000000;
1347 9 return was_shrunk;
1348 }
1349
1350 /**
1351 Read one command from connection and execute it (query or simple command).
1352 This function is called in loop from thread function.
1353
1354 For profiling to work, it must never be called recursively.
1355
1356 @retval
1357 0 success
1358 @retval
1359 1 request of thread shutdown (see dispatch_command() description)
1360 */
1361
1362 11090017 bool do_command(THD *thd) {
1363 bool return_value;
1364 int rc;
1365 11090017 NET *net = nullptr;
1366 11090017 enum enum_server_command command = COM_SLEEP;
1367 COM_DATA com_data;
1368
1/2
✓ Branch 0 taken 11091979 times.
✗ Branch 1 not taken.
11090017 DBUG_TRACE;
1369
2/4
✓ Branch 0 taken 11091834 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11091834 times.
11091979 assert(thd->is_classic_protocol());
1370
1371 /*
1372 indicator of uninitialized lex => normal flow of errors handling
1373 (see my_message_sql)
1374 */
1375
1/2
✓ Branch 0 taken 11092003 times.
✗ Branch 1 not taken.
11091834 thd->lex->set_current_query_block(nullptr);
1376
1377 /*
1378 XXX: this code is here only to clear possible errors of init_connect.
1379 Consider moving to prepare_new_connection_state() instead.
1380 That requires making sure the DA is cleared before non-parsing statements
1381 such as COM_QUIT.
1382 */
1383
1/2
✓ Branch 0 taken 11092302 times.
✗ Branch 1 not taken.
11092003 thd->clear_error(); // Clear error message
1384
1/2
✓ Branch 0 taken 11092376 times.
✗ Branch 1 not taken.
11092302 thd->get_stmt_da()->reset_diagnostics_area();
1385 11092376 thd->updated_row_count = 0;
1386 11092376 thd->busy_time = 0;
1387 11092376 thd->cpu_time = 0;
1388 11092376 thd->bytes_received = 0;
1389 11092376 thd->bytes_sent = 0;
1390 11092376 thd->binlog_bytes_written = 0;
1391
1392 /*
1393 This thread will do a blocking read from the client which
1394 will be interrupted when the next command is received from
1395 the client, the connection is closed or "net_wait_timeout"
1396 number of seconds has passed.
1397 */
1398
2/4
✓ Branch 0 taken 11092262 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11091490 times.
✗ Branch 3 not taken.
11092376 net = thd->get_protocol_classic()->get_net();
1399
2/2
✓ Branch 0 taken 11087359 times.
✓ Branch 1 taken 4131 times.
11091490 if (!thd->skip_wait_timeout)
1400
1/2
✓ Branch 0 taken 11088226 times.
✗ Branch 1 not taken.
11087359 my_net_set_read_timeout(net, thd->get_wait_timeout());
1401 11092357 net_new_transaction(net);
1402
1403 /*
1404 Synchronization point for testing of KILL_CONNECTION.
1405 This sync point can wait here, to simulate slow code execution
1406 between the last test of thd->killed and blocking in read().
1407
1408 The goal of this test is to verify that a connection does not
1409 hang, if it is killed at this point of execution.
1410 (Bug#37780 - main.kill fails randomly)
1411
1412 Note that the sync point wait itself will be terminated by a
1413 kill. In this case it consumes a condition broadcast, but does
1414 not change anything else. The consumed broadcast should not
1415 matter here, because the read/recv() below doesn't use it.
1416 */
1417
3/4
✓ Branch 0 taken 11087696 times.
✓ Branch 1 taken 4277 times.
✓ Branch 2 taken 11087870 times.
✗ Branch 3 not taken.
11092357 DEBUG_SYNC(thd, "before_do_command_net_read");
1418
1419 /* For per-query performance counters with log_slow_statement */
1420 struct System_status_var query_start_status;
1421 11092147 thd->clear_copy_status_var();
1422
2/2
✓ Branch 0 taken 507 times.
✓ Branch 1 taken 11091126 times.
11091633 if (opt_log_slow_extra) {
1423 507 thd->copy_status_var(&query_start_status);
1424 }
1425
1426
1/2
✓ Branch 0 taken 11091610 times.
✗ Branch 1 not taken.
11091633 rc = thd->m_mem_cnt.reset();
1427
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 11091608 times.
11091610 if (rc)
1428
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
2 thd->m_mem_cnt.set_thd_error_status();
1429 else {
1430 /*
1431 Because of networking layer callbacks in place,
1432 this call will maintain the following instrumentation:
1433 - IDLE events
1434 - SOCKET events
1435 - STATEMENT events
1436 - STAGE events
1437 when reading a new network packet.
1438 In particular, a new instrumented statement is started.
1439 See init_net_server_extension()
1440 */
1441 11091608 thd->m_server_idle = true;
1442
1/2
✓ Branch 0 taken 11091145 times.
✗ Branch 1 not taken.
11091608 rc = thd->get_protocol()->get_command(&com_data, &command);
1443 11091145 thd->m_server_idle = false;
1444 }
1445
1446
2/2
✓ Branch 0 taken 3590 times.
✓ Branch 1 taken 11087564 times.
11091154 if (rc) {
1447 #ifndef NDEBUG
1448 char desc[VIO_DESCRIPTION_SIZE];
1449
1/2
✓ Branch 0 taken 3591 times.
✗ Branch 1 not taken.
3590 vio_description(net->vio, desc);
1450
3/8
✓ Branch 0 taken 3591 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3590 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3590 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
3591 DBUG_PRINT("info", ("Got error %d reading command from socket %s",
1451 net->error, desc));
1452 #endif // NDEBUG
1453 /* Instrument this broken statement as "statement/com/error" */
1454
1/2
✓ Branch 0 taken 3590 times.
✗ Branch 1 not taken.
3590 thd->m_statement_psi = MYSQL_REFINE_STATEMENT(
1455 thd->m_statement_psi, com_statement_info[COM_END].m_key);
1456
1457 /* Check if we can continue without closing the connection */
1458
1459 /* The error must be set. */
1460
2/4
✓ Branch 0 taken 3590 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3590 times.
3590 assert(thd->is_error());
1461
1/2
✓ Branch 0 taken 3590 times.
✗ Branch 1 not taken.
3590 thd->send_statement_status();
1462
1463 /* Mark the statement completed. */
1464
1/2
✓ Branch 0 taken 3589 times.
✗ Branch 1 not taken.
3590 MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
1465 3589 thd->m_statement_psi = nullptr;
1466 3589 thd->m_digest = nullptr;
1467
1468
2/2
✓ Branch 0 taken 3587 times.
✓ Branch 1 taken 2 times.
3589 if (rc < 0) {
1469 3587 return_value = true; // We have to close it.
1470 3587 goto out;
1471 }
1472 2 net->error = NET_ERROR_UNSET;
1473 2 return_value = false;
1474 2 goto out;
1475 }
1476
1477 #ifndef NDEBUG
1478 char desc[VIO_DESCRIPTION_SIZE];
1479
1/2
✓ Branch 0 taken 11087349 times.
✗ Branch 1 not taken.
11087564 vio_description(net->vio, desc);
1480
5/8
✓ Branch 0 taken 11087468 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11087474 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 202 times.
✓ Branch 5 taken 11087272 times.
✓ Branch 6 taken 202 times.
✗ Branch 7 not taken.
11087349 DBUG_PRINT("info", ("Command on %s = %d (%s)", desc, command,
1481 Command_names::str_notranslate(command).c_str()));
1482 #endif // NDEBUG
1483
1484 #ifdef WITH_WSREP
1485 /*
1486 Aborted by background rollbacker thread.
1487 Handle error here and jump straight to out
1488 */
1489
3/4
✓ Branch 0 taken 11087461 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 64 times.
✓ Branch 3 taken 11087397 times.
11087474 if (wsrep_before_command(thd)) {
1490
1/2
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
64 thd->store_globals();
1491
1/2
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
64 WSREP_LOG_THD(thd, "enter found BF aborted");
1492 /* We don't expect stmt/transactional locks. Explicit locks are allowed */
1493
2/4
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 64 times.
64 assert(!thd->mdl_context.has_stmt_locks());
1494
2/4
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 64 times.
64 assert(!thd->mdl_context.has_transactional_locks());
1495
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
64 assert(!thd->get_stmt_da()->is_set());
1496 /* We let COM_QUIT and COM_STMT_CLOSE to execute even if wsrep aborted. */
1497
3/4
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53 times.
✓ Branch 3 taken 11 times.
64 if (command != COM_STMT_CLOSE && command != COM_QUIT) {
1498
1/2
✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
53 my_error(ER_LOCK_DEADLOCK, MYF(0));
1499
1/26
✗ Branch 0 not taken.
✓ Branch 1 taken 53 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
53 WSREP_DEBUG("Deadlock error for: %s", thd->query().str);
1500 53 thd->killed = THD::NOT_KILLED;
1501 53 thd->wsrep_retry_counter = 0;
1502
1503 /* Instrument this broken statement as "statement/com/error" */
1504
1/2
✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
53 thd->m_statement_psi = MYSQL_REFINE_STATEMENT(
1505 thd->m_statement_psi, com_statement_info[COM_END].m_key);
1506
1507
1/2
✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
53 thd->send_statement_status();
1508
1509 /* Mark the statement completed. */
1510
1/2
✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
53 MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
1511 53 thd->m_statement_psi = NULL;
1512 53 thd->m_digest = NULL;
1513 53 return_value = false;
1514
1515
1/2
✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
53 wsrep_after_command_before_result(thd);
1516 53 goto out;
1517 }
1518 }
1519
1520
7/8
✓ Branch 0 taken 11087314 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 164973 times.
✓ Branch 3 taken 10922341 times.
✓ Branch 4 taken 164973 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 162403 times.
✓ Branch 7 taken 2570 times.
11087408 if (WSREP(thd)) {
1521 /*
1522 * bail out if DB snapshot has not been installed. We however,
1523 * allow queries "SET" and "SHOW", they are trapped later in execute_command
1524 */
1525 487209 if (!thd->wsrep_applier &&
1526
7/10
✓ Branch 0 taken 162403 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 162403 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 161253 times.
✓ Branch 5 taken 1150 times.
✓ Branch 6 taken 7 times.
✓ Branch 7 taken 161246 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 162403 times.
163560 (!wsrep_ready_get() || wsrep_reject_queries != WSREP_REJECT_NONE) &&
1527
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1157 times.
1157 (server_command_flags[command] & CF_SKIP_WSREP_CHECK) == 0) {
1528 my_message(ER_UNKNOWN_COM_ERROR,
1529 "WSREP has not yet prepared node for application use", MYF(0));
1530 thd->end_statement();
1531
1532 /* Performance Schema Interface instrumentation end */
1533 MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
1534 thd->m_statement_psi = NULL;
1535 thd->m_digest = NULL;
1536
1537 return_value = false;
1538 wsrep_after_command_before_result(thd);
1539 goto out;
1540 }
1541 }
1542 #endif /* WITH_WSREP */
1543
1544
7/12
✓ Branch 0 taken 11087384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11087416 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 202 times.
✓ Branch 5 taken 11087214 times.
✓ Branch 6 taken 202 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 202 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 202 times.
✗ Branch 11 not taken.
11087408 DBUG_PRINT("info", ("packet: '%*.s'; command: %d",
1545 (int)thd->get_protocol_classic()->get_packet_length(),
1546 thd->get_protocol_classic()->get_raw_packet(), command));
1547
2/4
✓ Branch 0 taken 11087332 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11087332 times.
11087416 if (thd->get_protocol_classic()->bad_packet)
1548 assert(0); // Should be caught earlier
1549
1550 // Reclaim some memory
1551
3/6
✓ Branch 0 taken 11087425 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11087362 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11087411 times.
✗ Branch 5 not taken.
11087332 thd->get_protocol_classic()->get_output_packet()->shrink(
1552 thd->variables.net_buffer_length);
1553 /* Restore read timeout value */
1554
1/2
✓ Branch 0 taken 11087639 times.
✗ Branch 1 not taken.
11087411 my_net_set_read_timeout(net, thd->variables.net_read_timeout);
1555
1556 11087639 thd->status_var.net_buffer_length = net->max_packet;
1557
1558
3/4
✓ Branch 0 taken 11083624 times.
✓ Branch 1 taken 3909 times.
✓ Branch 2 taken 11083694 times.
✗ Branch 3 not taken.
11087639 DEBUG_SYNC(thd, "before_command_dispatch");
1559
1560
1/2
✓ Branch 0 taken 11084550 times.
✗ Branch 1 not taken.
11087603 return_value = dispatch_command(thd, &com_data, command);
1561
1562 #ifdef MYSQL_SERVER
1563 {
1564 11084550 NET_SERVER *ext = static_cast<NET_SERVER *>(net->extension);
1565
1/2
✓ Branch 0 taken 11085693 times.
✗ Branch 1 not taken.
11084550 if (ext != nullptr)
1566
1/2
✓ Branch 0 taken 11085747 times.
✗ Branch 1 not taken.
11085693 shrink_packet_buffer(thd, &ext->max_interval_packet,
1567 &ext->net_buffer_shrink_time);
1568 }
1569 #endif
1570
1571
3/6
✓ Branch 0 taken 11085400 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11085412 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11085401 times.
✗ Branch 5 not taken.
11084604 thd->get_protocol_classic()->get_output_packet()->shrink(
1572 thd->variables.net_buffer_length);
1573
1574 11089043 out:
1575 /* The statement instrumentation must be closed in all cases. */
1576
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11089043 times.
11089043 assert(thd->m_digest == nullptr);
1577
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11089043 times.
11089043 assert(thd->m_statement_psi == nullptr);
1578 #ifdef WITH_WSREP
1579 // TODO: Need to findout significance of bad packet and execution of API
1580
3/4
✓ Branch 0 taken 11088310 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11085426 times.
✓ Branch 3 taken 2884 times.
11089043 if (!thd->get_protocol_classic()->bad_packet) {
1581 /* there was a command to process, and before_command() has been called */
1582
1/2
✓ Branch 0 taken 11085350 times.
✗ Branch 1 not taken.
11085426 wsrep_after_command_after_result(thd);
1583 }
1584 #endif /* WITH_WSREP */
1585 11089715 return return_value;
1586 11088234 }
1587
1588 /**
1589 @brief Determine if an attempt to update a non-temporary table while the
1590 read-only option was enabled has been made.
1591
1592 This is a helper function to mysql_execute_command.
1593
1594 @note SQLCOM_UPDATE_MULTI is an exception and delt with elsewhere.
1595
1596 @see mysql_execute_command
1597 @returns Status code
1598 @retval true The statement should be denied.
1599 @retval false The statement isn't updating any relevant tables.
1600 */
1601 21005693 static bool deny_updates_if_read_only_option(THD *thd, TABLE_LIST *all_tables) {
1602
1/2
✓ Branch 0 taken 21006377 times.
✗ Branch 1 not taken.
21005693 DBUG_TRACE;
1603
1604
3/4
✓ Branch 0 taken 21005856 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20713169 times.
✓ Branch 3 taken 292687 times.
21006377 if (!check_readonly(thd, false)) return false;
1605
1606 292687 LEX *lex = thd->lex;
1607
2/2
✓ Branch 0 taken 292529 times.
✓ Branch 1 taken 158 times.
292687 if (!(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA)) return false;
1608
1609 /* Multi update is an exception and is dealt with later. */
1610
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 152 times.
158 if (lex->sql_command == SQLCOM_UPDATE_MULTI) return false;
1611
1612 152 const bool create_temp_tables =
1613
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 118 times.
186 (lex->sql_command == SQLCOM_CREATE_TABLE) &&
1614
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 15 times.
34 (lex->create_info->options & HA_LEX_CREATE_TMP_TABLE);
1615
1616 152 const bool create_real_tables =
1617
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 118 times.
186 (lex->sql_command == SQLCOM_CREATE_TABLE) &&
1618
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 19 times.
34 !(lex->create_info->options & HA_LEX_CREATE_TMP_TABLE);
1619
1620 152 const bool drop_temp_tables =
1621
3/4
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 141 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
152 (lex->sql_command == SQLCOM_DROP_TABLE) && lex->drop_temporary;
1622
1623 /* RENAME TABLES ignores shadowing temporary tables. */
1624 152 const bool rename_tables = (lex->sql_command == SQLCOM_RENAME_TABLE);
1625
1626 const bool update_real_tables =
1627
2/2
✓ Branch 0 taken 162 times.
✓ Branch 1 taken 1 times.
163 ((create_real_tables || rename_tables ||
1628
4/6
✓ Branch 0 taken 163 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 162 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 74 times.
✓ Branch 5 taken 88 times.
378 some_non_temp_table_to_be_updated(thd, all_tables)) &&
1629
2/4
✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 71 times.
✗ Branch 3 not taken.
64 !(create_temp_tables || drop_temp_tables));
1630
1631 152 const bool create_or_drop_databases =
1632
1/2
✓ Branch 0 taken 177 times.
✗ Branch 1 not taken.
329 (lex->sql_command == SQLCOM_CREATE_DB) ||
1633
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 176 times.
177 (lex->sql_command == SQLCOM_DROP_DB);
1634
1635 152 const bool create_or_drop_compression_dictionary =
1636
1/2
✓ Branch 0 taken 178 times.
✗ Branch 1 not taken.
330 (lex->sql_command == SQLCOM_CREATE_COMPRESSION_DICTIONARY) ||
1637
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 178 times.
178 (lex->sql_command == SQLCOM_DROP_COMPRESSION_DICTIONARY);
1638
1639
5/6
✓ Branch 0 taken 107 times.
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 105 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 105 times.
152 if (update_real_tables || create_or_drop_databases ||
1640 create_or_drop_compression_dictionary) {
1641 /*
1642 An attempt was made to modify one or more non-temporary tables.
1643 */
1644 47 return true;
1645 }
1646
1647 /* Assuming that only temporary tables are modified. */
1648 105 return false;
1649 21005856 }
1650
1651 #ifdef WITH_WSREP
1652 151735 static bool wsrep_read_only_option(THD *thd, TABLE_LIST *all_tables) {
1653 151735 int opt_readonly_saved = opt_readonly;
1654
1655 151735 ulong master_access = thd->security_context()->master_access();
1656 151736 ulong flag_saved = (ulong)(master_access & SUPER_ACL);
1657
1658 151736 opt_readonly = 0;
1659 151736 thd->security_context()->set_master_access(master_access & ~SUPER_ACL);
1660
1661 151736 bool ret = !deny_updates_if_read_only_option(thd, all_tables);
1662
1663 151736 opt_readonly = opt_readonly_saved;
1664 151736 thd->security_context()->set_master_access(master_access | flag_saved);
1665
1666 151737 return ret;
1667 }
1668
1669 165 static void wsrep_copy_query(THD *thd) {
1670 165 thd->wsrep_retry_command = thd->get_command();
1671 165 thd->wsrep_retry_query_len = thd->query().length;
1672
2/2
✓ Branch 0 taken 116 times.
✓ Branch 1 taken 49 times.
165 if (thd->wsrep_retry_query) {
1673 116 my_free(thd->wsrep_retry_query);
1674 }
1675 330 thd->wsrep_retry_query = (char *)my_malloc(
1676 165 key_memory_wsrep, thd->wsrep_retry_query_len + 1, MYF(0));
1677 165 strncpy(thd->wsrep_retry_query, thd->query().str, thd->wsrep_retry_query_len);
1678 165 thd->wsrep_retry_query[thd->wsrep_retry_query_len] = '\0';
1679 165 }
1680
1681 /* Function should be called if any non-supported lock/unlock statement
1682 is executed and if the outcome has to be evaluated based on pxc-strict-mode */
1683 3281 static bool pxc_strict_mode_lock_check(THD *thd) {
1684 /* LOCK/UNLOCK TABLE is not supported by galera due as it not compatible
1685 with multi-master semantics. */
1686 3281 bool block = false;
1687
1688
3/3
✓ Branch 0 taken 3273 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
3281 switch (pxc_strict_mode) {
1689 3273 case PXC_STRICT_MODE_DISABLED:
1690 case PXC_STRICT_MODE_MASTER:
1691 /* Do nothing */
1692 3273 break;
1693 4 case PXC_STRICT_MODE_PERMISSIVE:
1694
10/22
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 4 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 4 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 4 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 4 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
4 WSREP_WARN(
1695 "Percona-XtraDB-Cluster doesn't recommend use of"
1696 " LOCK TABLE/FLUSH TABLE <table> WITH READ LOCK/FOR EXPORT"
1697 " with pxc_strict_mode = PERMISSIVE");
1698
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 push_warning_printf(thd, Sql_condition::SL_WARNING, ER_UNKNOWN_ERROR,
1699 "Percona-XtraDB-Cluster doesn't recommend use of"
1700 " LOCK TABLE/FLUSH TABLE <table> WITH READ LOCK"
1701 " with pxc_strict_mode = PERMISSIVE");
1702 4 break;
1703 4 case PXC_STRICT_MODE_ENFORCING:
1704 default:
1705 4 block = true;
1706
13/28
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 4 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 4 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 4 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 4 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 4 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 4 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 4 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
4 WSREP_ERROR(
1707 "Percona-XtraDB-Cluster prohibits use of"
1708 " LOCK TABLE/FLUSH TABLE <table> WITH READ LOCK/FOR EXPORT"
1709 " with pxc_strict_mode = ENFORCING");
1710 char message[1024];
1711 4 sprintf(message,
1712 "Percona-XtraDB-Cluster prohibits use of"
1713 " LOCK TABLE/FLUSH TABLE <table> WITH READ LOCK/FOR EXPORT"
1714 " with pxc_strict_mode = ENFORCING");
1715
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 my_message(ER_UNKNOWN_ERROR, message, MYF(0));
1716 4 break;
1717 }
1718
1719 3281 return block;
1720 }
1721 /*
1722 * This function should be called to determine if cluster still has nodes
1723 * with lower versions of wsrep_protocol_version (eg.: version 3).
1724 * Writing on a new node can crash nodes with lower version 8.0->5.7
1725 */
1726 279402 static bool block_write_while_in_rolling_upgrade(THD *thd) {
1727 /* Ignore check while server is not ready or for background wsrep applier too
1728 * (like slave thread) */
1729
10/14
✓ Branch 0 taken 268660 times.
✓ Branch 1 taken 10887 times.
✓ Branch 2 taken 268661 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 268661 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 268661 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 268661 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 32222 times.
✓ Branch 11 taken 236439 times.
✓ Branch 12 taken 43105 times.
✓ Branch 13 taken 236442 times.
279402 if (!wsrep_node_is_synced() || (WSREP(thd) && thd->wsrep_applier))
1730 43105 return false;
1731
1732 236442 bool block = false;
1733 236442 LEX *lex = thd->lex;
1734
2/2
✓ Branch 0 taken 44994 times.
✓ Branch 1 taken 191448 times.
236442 if (sql_command_flags[lex->sql_command] & CF_CHANGES_DATA) {
1735 44994 bool multi_version_cluster = wsrep_protocol_version < 4;
1736
3/4
✓ Branch 0 taken 44994 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 44987 times.
89987 if (multi_version_cluster ||
1737
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 44987 times.
44994 DBUG_EVALUATE_IF("simulate_wsrep_multiple_major_versions", true,
1738 false)) {
1739 const char *msg;
1740
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
6 switch (pxc_strict_mode) {
1741 case PXC_STRICT_MODE_DISABLED:
1742 /* Do nothing */
1743 break;
1744 3 case PXC_STRICT_MODE_PERMISSIVE:
1745 3 msg =
1746 "Percona-XtraDB-Cluster doesn't recommend use of multiple major"
1747 " versions while accepting write workload"
1748 " with pxc_strict_mode = PERMISSIVE";
1749
9/18
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 3 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 3 times.
3 WSREP_WARN("%s", msg);
1750 3 push_warning_printf(thd, Sql_condition::SL_WARNING, ER_UNKNOWN_ERROR,
1751 "%s", msg);
1752 3 break;
1753 3 case PXC_STRICT_MODE_MASTER:
1754 case PXC_STRICT_MODE_ENFORCING:
1755 default:
1756 3 block = true;
1757 3 msg =
1758 "Percona-XtraDB-Cluster prohibits use of multiple major versions"
1759 " while accepting write workload with pxc_strict_mode = "
1760 "ENFORCING or MASTER";
1761
12/24
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 3 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 3 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 3 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 3 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 3 times.
3 WSREP_ERROR("%s", msg);
1762 3 my_message(ER_UNKNOWN_ERROR, msg, MYF(0));
1763 3 break;
1764 }
1765 }
1766 }
1767 236441 return block;
1768 }
1769 #endif /* WITH_WSREP */
1770
1771 /**
1772 Check if a statement should be restarted in another storage engine,
1773 and restart the statement if needed.
1774
1775 @param thd the session
1776 @param parser_state the parser state
1777 @param query_string the query to reprepare and execute
1778 @param query_length the length of the query
1779 */
1780 11101970 static void check_secondary_engine_statement(THD *thd,
1781 Parser_state *parser_state,
1782 const char *query_string,
1783 size_t query_length) {
1784 #ifdef WITH_WSREP
1785
6/8
✓ Branch 0 taken 11102050 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 162900 times.
✓ Branch 3 taken 10939150 times.
✓ Branch 4 taken 162901 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 157756 times.
✓ Branch 7 taken 5145 times.
11101970 if (WSREP(thd)) {
1786 /* While running in cluster mode disable the check for now */
1787 157756 return;
1788 }
1789 #endif /* WITH_WSREP */
1790
1791 10944214 bool use_secondary_engine = false;
1792
1793 // Only restart the statement if a non-fatal error was raised.
1794
8/8
✓ Branch 0 taken 77235 times.
✓ Branch 1 taken 10867391 times.
✓ Branch 2 taken 76970 times.
✓ Branch 3 taken 265 times.
✓ Branch 4 taken 438 times.
✓ Branch 5 taken 76566 times.
✓ Branch 6 taken 10868180 times.
✓ Branch 7 taken 76480 times.
10944214 if (!thd->is_error() || thd->is_killed() || thd->is_fatal_error()) return;
1795
1796 // Only SQL commands can be restarted with another storage engine.
1797
2/2
✓ Branch 0 taken 36800 times.
✓ Branch 1 taken 39680 times.
76480 if (thd->lex->m_sql_cmd == nullptr) return;
1798
1799 // The query cannot be restarted if it had started executing, since
1800 // it may have started sending results to the client.
1801
2/2
✓ Branch 0 taken 7941 times.
✓ Branch 1 taken 31825 times.
39680 if (thd->lex->is_exec_completed()) return;
1802
1803 // Decide which storage engine to use when retrying.
1804
3/3
✓ Branch 0 taken 31669 times.
✓ Branch 1 taken 131 times.
✓ Branch 2 taken 25 times.
31825 switch (thd->secondary_engine_optimization()) {
1805 31669 case Secondary_engine_optimization::PRIMARY_TENTATIVELY:
1806 // If a request to prepare for the secondary engine was
1807 // signalled, retry in the secondary engine.
1808
2/2
✓ Branch 0 taken 31436 times.
✓ Branch 1 taken 233 times.
31669 if (thd->get_stmt_da()->mysql_errno() != ER_PREPARE_FOR_SECONDARY_ENGINE)
1809 31436 return;
1810 233 thd->set_secondary_engine_optimization(
1811 Secondary_engine_optimization::SECONDARY);
1812 233 use_secondary_engine = true;
1813 233 break;
1814 131 case Secondary_engine_optimization::SECONDARY:
1815 // If the query failed during offloading to a secondary engine,
1816 // retry in the primary engine. Don't retry if the failing query
1817 // was already using the primary storage engine.
1818
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 124 times.
131 if (!thd->lex->m_sql_cmd->using_secondary_storage_engine()) return;
1819 124 thd->set_secondary_engine_optimization(
1820 Secondary_engine_optimization::PRIMARY_ONLY);
1821 124 break;
1822 25 default:
1823 25 return;
1824 }
1825
1826 // Forget about the error raised in the previous attempt at preparing the
1827 // query.
1828 357 thd->clear_error();
1829
1830 // Tell performance schema that the statement is restarted.
1831 357 MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
1832
1833 357 mysql_thread_set_secondary_engine(use_secondary_engine);
1834
1835 357 thd->m_statement_psi = MYSQL_START_STATEMENT(
1836 &thd->m_statement_state, com_statement_info[thd->get_command()].m_key,
1837 thd->db().str, thd->db().length, thd->charset(), nullptr);
1838
1839 357 mysql_statement_set_secondary_engine(thd->m_statement_psi,
1840 use_secondary_engine);
1841
1842
1/2
✓ Branch 0 taken 357 times.
✗ Branch 1 not taken.
357 DEBUG_SYNC(thd, "retry_secondary_engine");
1843
1844 // Reset the statement digest state.
1845 357 thd->m_digest = &thd->m_digest_state;
1846 357 thd->m_digest->reset(thd->m_token_array, max_digest_length);
1847
1848 // Reset the parser state.
1849 357 thd->set_query(query_string, query_length);
1850 357 parser_state->reset(query_string, query_length);
1851
1852 // Disable the general log. The query was written to the general log in the
1853 // first attempt to execute it. No need to write it twice.
1854 357 const uint64_t saved_option_bits = thd->variables.option_bits;
1855 357 thd->variables.option_bits |= OPTION_LOG_OFF;
1856
1857 // Restart the statement.
1858 357 dispatch_sql_command(thd, parser_state, true);
1859
1860 // Restore the original option bits.
1861 357 thd->variables.option_bits = saved_option_bits;
1862
1863 // Check if the restarted statement failed, and if so, if it needs
1864 // another restart/fallback to the primary storage engine.
1865 357 check_secondary_engine_statement(thd, parser_state, query_string,
1866 query_length);
1867 }
1868
1869 /*Reference to the GR callback that receives incoming connections*/
1870 static std::atomic<gr_incoming_connection_cb> com_incoming_gr_stream_cb;
1871
1872 2484 void set_gr_incoming_connection(gr_incoming_connection_cb x) {
1873 2484 com_incoming_gr_stream_cb.store(x);
1874 2484 }
1875
1876 810 gr_incoming_connection_cb get_gr_incoming_connection() {
1877 810 gr_incoming_connection_cb retval = nullptr;
1878 810 retval = com_incoming_gr_stream_cb.load();
1879 810 return retval;
1880 }
1881
1882 368 void call_gr_incoming_connection_cb(THD *thd, int fd, SSL *ssl_ctx) {
1883 gr_incoming_connection_cb gr_connection_callback =
1884 368 get_gr_incoming_connection();
1885
1886
1/2
✓ Branch 0 taken 368 times.
✗ Branch 1 not taken.
368 if (gr_connection_callback) {
1887
1/2
✓ Branch 0 taken 368 times.
✗ Branch 1 not taken.
368 gr_connection_callback(thd, fd, ssl_ctx);
1888
1889 368 PSI_stage_info saved_stage;
1890
1/2
✓ Branch 0 taken 368 times.
✗ Branch 1 not taken.
368 mysql_mutex_lock(&thd->LOCK_group_replication_connection_mutex);
1891
1/2
✓ Branch 0 taken 368 times.
✗ Branch 1 not taken.
368 thd->ENTER_COND(&thd->COND_group_replication_connection_cond_var,
1892 &thd->LOCK_group_replication_connection_mutex,
1893 &stage_communication_delegation, &saved_stage);
1894
2/2
✓ Branch 0 taken 1701 times.
✓ Branch 1 taken 367 times.
2068 while (thd->is_killed() == THD::NOT_KILLED) {
1895 struct timespec abstime;
1896
1/2
✓ Branch 0 taken 1701 times.
✗ Branch 1 not taken.
1701 set_timespec(&abstime, 1);
1897
1/2
✓ Branch 0 taken 1700 times.
✗ Branch 1 not taken.
1701 mysql_cond_timedwait(&thd->COND_group_replication_connection_cond_var,
1898 &thd->LOCK_group_replication_connection_mutex,
1899 &abstime);
1900 }
1901
1/2
✓ Branch 0 taken 368 times.
✗ Branch 1 not taken.
367 mysql_mutex_unlock(&thd->LOCK_group_replication_connection_mutex);
1902
1/2
✓ Branch 0 taken 368 times.
✗ Branch 1 not taken.
368 thd->EXIT_COND(&saved_stage);
1903 }
1904 368 }
1905
1906 /**
1907 Deep copy the name and value of named parameters into the THD memory.
1908
1909 We need to do this since the packet bytes will go away during query
1910 processing.
1911 It doesn't need to be done for the unnamed ones since they're being
1912 copied by and into Item_param. So we don't want to duplicate this.
1913 @sa @ref Item_param
1914
1915 @param thd the thread to copy the parameters to.
1916 @param parameters the values to copy
1917 @param count the number of parameters to copy
1918 */
1919 11027774 static void copy_bind_parameter_values(THD *thd, PS_PARAM *parameters,
1920 unsigned long count) {
1921 11027774 thd->bind_parameter_values = parameters;
1922 11027774 thd->bind_parameter_values_count = count;
1923 unsigned long inx;
1924 PS_PARAM *par;
1925
2/2
✓ Branch 0 taken 135249 times.
✓ Branch 1 taken 11027774 times.
11163023 for (inx = 0, par = thd->bind_parameter_values; inx < count; inx++, par++) {
1926
3/4
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 135210 times.
✓ Branch 2 taken 39 times.
✗ Branch 3 not taken.
135249 if (par->name_length && par->name) {
1927 39 void *newd = thd->alloc(par->name_length);
1928 39 memcpy(newd, par->name, par->name_length);
1929 39 par->name = reinterpret_cast<unsigned char *>(newd);
1930 }
1931
3/4
✓ Branch 0 taken 135136 times.
✓ Branch 1 taken 113 times.
✓ Branch 2 taken 135136 times.
✗ Branch 3 not taken.
135249 if (par->length && par->value) {
1932 135136 void *newd = thd->alloc(par->length);
1933 135136 memcpy(newd, par->value, par->length);
1934 135136 par->value = reinterpret_cast<unsigned char *>(newd);
1935 }
1936 }
1937 11027774 }
1938
1939 /**
1940 Perform one connection-level (COM_XXXX) command.
1941
1942 @param thd connection handle
1943 @param command type of command to perform
1944 @param com_data com_data union to store the generated command
1945
1946 @todo
1947 set thd->lex->sql_command to SQLCOM_END here.
1948 @todo
1949 The following has to be changed to an 8 byte integer
1950
1951 @retval
1952 0 ok
1953 @retval
1954 1 request of thread shutdown, i. e. if command is
1955 COM_QUIT
1956 */
1957 11178499 bool dispatch_command(THD *thd, const COM_DATA *com_data,
1958 enum enum_server_command command) {
1959
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11178591 times.
11178499 assert(thd->lex->m_IS_table_stats.is_valid() == false);
1960
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11178586 times.
11178591 assert(thd->lex->m_IS_tablespace_stats.is_valid() == false);
1961 #ifndef NDEBUG
1962 11176068 auto tabstat_grd = create_scope_guard([&]() {
1963
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11176303 times.
11176068 assert(thd->lex->m_IS_table_stats.is_valid() == false);
1964
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11176504 times.
11176303 assert(thd->lex->m_IS_tablespace_stats.is_valid() == false);
1965
1/2
✓ Branch 0 taken 11178488 times.
✗ Branch 1 not taken.
11178586 });
1966 #endif /* NDEBUG */
1967 11178488 bool error = false;
1968 11178488 Global_THD_manager *thd_manager = Global_THD_manager::get_instance();
1969
1/2
✓ Branch 0 taken 11178635 times.
✗ Branch 1 not taken.
11178406 DBUG_TRACE;
1970
5/8
✓ Branch 0 taken 11178604 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11178502 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 202 times.
✓ Branch 5 taken 11178300 times.
✓ Branch 6 taken 202 times.
✗ Branch 7 not taken.
11178635 DBUG_PRINT("info", ("command: %d", command));
1971
1972
2/14
✓ Branch 0 taken 11178456 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11178456 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
11178502 DBUG_EXECUTE_IF("crash_dispatch_command_before", {
1973 DBUG_PRINT("crash_dispatch_command_before", ("now"));
1974 DBUG_ABORT();
1975 });
1976
1977 11178456 Sql_cmd_clone *clone_cmd = nullptr;
1978
1979 /* SHOW PROFILE instrumentation, begin */
1980 #if defined(ENABLED_PROFILING)
1981
1/2
✓ Branch 0 taken 11178648 times.
✗ Branch 1 not taken.
11178456 thd->profiling->start_new_query();
1982 #endif
1983
1984 /* Performance Schema Interface instrumentation, begin */
1985
1/2
✓ Branch 0 taken 11178531 times.
✗ Branch 1 not taken.
11178648 thd->m_statement_psi = MYSQL_REFINE_STATEMENT(
1986 thd->m_statement_psi, com_statement_info[command].m_key);
1987
1988
1/2
✓ Branch 0 taken 11178430 times.
✗ Branch 1 not taken.
11178531 thd->set_command(command);
1989 /*
1990 Commands which always take a long time are logged into
1991 the slow log only if opt_log_slow_admin_statements is set.
1992 */
1993 11178430 thd->enable_slow_log = true;
1994 // Both this and the call THD::reset_for_next_command are required, even if
1995 // clear_slow_extended ends up being called twice in common execution path
1996 // between successive commands, because some COM_* skip one or another, i.e.
1997 // COM_QUIT needs this one.
1998 11178430 thd->clear_slow_extended();
1999 11178635 thd->lex->sql_command = SQLCOM_END; /* to avoid confusing VIEW detectors */
2000 /*
2001 KILL QUERY may come after cleanup in mysql_execute_command(). Next query
2002 execution is interrupted due to this. So resetting THD::killed here.
2003
2004 THD::killed value can not be KILL_TIMEOUT here as timer used for statement
2005 max execution time is disarmed in the cleanup stage of
2006 mysql_execute_command. KILL CONNECTION should terminate the connection.
2007 Hence resetting THD::killed only for KILL QUERY case here.
2008 */
2009
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 11178520 times.
11178635 if (thd->killed == THD::KILL_QUERY) thd->killed = THD::NOT_KILLED;
2010
1/2
✓ Branch 0 taken 11178492 times.
✗ Branch 1 not taken.
11178521 thd->set_time();
2011
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11178226 times.
11178492 if (is_time_t_valid_for_timestamp(thd->query_start_in_secs()) == false) {
2012 /*
2013 If the time has gone past end of epoch we need to shutdown the server. But
2014 there is possibility of getting invalid time value on some platforms.
2015 For example, gettimeofday() might return incorrect value on solaris
2016 platform. Hence validating the current time with 5 iterations before
2017 initiating the normal server shutdown process because of time getting
2018 past 2038.
2019 */
2020 const int max_tries = 5;
2021 LogErr(WARNING_LEVEL, ER_CONFIRMING_THE_FUTURE, max_tries);
2022
2023 int tries = 0;
2024 while (++tries <= max_tries) {
2025 thd->set_time();
2026 if (is_time_t_valid_for_timestamp(thd->query_start_in_secs()) == true) {
2027 LogErr(WARNING_LEVEL, ER_BACK_IN_TIME, tries);
2028 break;
2029 }
2030 LogErr(WARNING_LEVEL, ER_FUTURE_DATE, tries);
2031 }
2032 if (tries > max_tries) {
2033 /*
2034 If the time has got past epoch, we need to shut this server down.
2035 We do this by making sure every command is a shutdown and we
2036 have enough privileges to shut the server down
2037
2038 TODO: remove this when we have full 64 bit my_time_t support
2039 */
2040 LogErr(ERROR_LEVEL, ER_UNSUPPORTED_DATE);
2041 ulong master_access = thd->security_context()->master_access();
2042 thd->security_context()->set_master_access(master_access | SHUTDOWN_ACL);
2043 error = true;
2044 kill_mysql();
2045 }
2046 }
2047
1/2
✓ Branch 0 taken 11178600 times.
✗ Branch 1 not taken.
11178226 thd->set_query_id(next_query_id());
2048
1/2
✓ Branch 0 taken 11178543 times.
✗ Branch 1 not taken.
11178600 thd->reset_rewritten_query();
2049 11178543 thd_manager->inc_thread_running();
2050
2051 #ifdef WITH_WSREP
2052
8/12
✓ Branch 0 taken 11178681 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 167565 times.
✓ Branch 3 taken 11011116 times.
✓ Branch 4 taken 167565 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 162429 times.
✓ Branch 7 taken 5136 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 162429 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 11178652 times.
11178652 if (WSREP(thd) && thd->wsrep_next_trx_id() == WSREP_UNDEFINED_TRX_ID) {
2053 thd->set_wsrep_next_trx_id(thd->query_id);
2054 WSREP_DEBUG("assigned new next trx id: %" PRIu64, thd->wsrep_next_trx_id());
2055 }
2056
2057 11178652 bool do_end_of_statement = true;
2058 #endif /* WITH_WSREP */
2059
2060
2/2
✓ Branch 0 taken 11169097 times.
✓ Branch 1 taken 9555 times.
11178652 if (!(server_command_flags[command] & CF_SKIP_QUESTIONS))
2061 11169097 thd->status_var.questions++;
2062
2063 /* Declare userstat variables and start timer */
2064 11178652 double start_busy_usecs = 0.0;
2065 11178652 double start_cpu_nsecs = 0.0;
2066
2/2
✓ Branch 0 taken 1691 times.
✓ Branch 1 taken 11176786 times.
11178652 if (unlikely(opt_userstat))
2067 1691 userstat_start_timer(&start_busy_usecs, &start_cpu_nsecs);
2068
2069 /**
2070 Clear the set of flags that are expected to be cleared at the
2071 beginning of each command.
2072 */
2073 11178477 thd->server_status &= ~SERVER_STATUS_CLEAR_SET;
2074
2075
4/6
✓ Branch 0 taken 11178498 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 90986 times.
✓ Branch 3 taken 11087512 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 11178498 times.
11269463 if (thd->get_protocol()->type() == Protocol::PROTOCOL_PLUGIN &&
2076
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 90986 times.
90986 !(server_command_flags[command] & CF_ALLOW_PROTOCOL_PLUGIN)) {
2077 my_error(ER_PLUGGABLE_PROTOCOL_COMMAND_NOT_SUPPORTED, MYF(0));
2078 thd->killed = THD::KILL_CONNECTION;
2079 error = true;
2080 goto done;
2081 }
2082
2083 /**
2084 Enforce password expiration for all RPC commands, except the
2085 following:
2086
2087 COM_QUERY/COM_STMT_PREPARE and COM_STMT_EXECUTE do a more
2088 fine-grained check later.
2089 COM_STMT_CLOSE and COM_STMT_SEND_LONG_DATA don't return anything.
2090 COM_PING only discloses information that the server is running,
2091 and that's available through other means.
2092 COM_QUIT should work even for expired statements.
2093 */
2094
5/6
✓ Branch 0 taken 11178502 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 210 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 11178499 times.
22357249 if (unlikely(thd->security_context()->password_expired() &&
2095
2/4
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
✗ Branch 3 not taken.
39 command != COM_QUERY && command != COM_STMT_CLOSE &&
2096
3/4
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 38 times.
39 command != COM_STMT_SEND_LONG_DATA && command != COM_PING &&
2097
4/6
✓ Branch 0 taken 249 times.
✓ Branch 1 taken 11178253 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
11178751 command != COM_QUIT && command != COM_STMT_PREPARE &&
2098 command != COM_STMT_EXECUTE)) {
2099
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_MUST_CHANGE_PASSWORD, MYF(0));
2100 1 goto done;
2101 }
2102
2103
3/4
✓ Branch 0 taken 11178512 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 11178508 times.
11178365 if (mysql_audit_notify(thd, AUDIT_EVENT(MYSQL_AUDIT_COMMAND_START), command,
2104
1/2
✓ Branch 0 taken 11178462 times.
✗ Branch 1 not taken.
11178499 Command_names::str_global(command).c_str())) {
2105 4 goto done;
2106 }
2107
2108
24/25
✓ Branch 0 taken 2635 times.
✓ Branch 1 taken 7125 times.
✓ Branch 2 taken 1286 times.
✓ Branch 3 taken 2157 times.
✓ Branch 4 taken 442 times.
✓ Branch 5 taken 235 times.
✓ Branch 6 taken 5174 times.
✓ Branch 7 taken 1815 times.
✓ Branch 8 taken 496 times.
✓ Branch 9 taken 4753 times.
✓ Branch 10 taken 4198 times.
✓ Branch 11 taken 57 times.
✓ Branch 12 taken 11022637 times.
✓ Branch 13 taken 14 times.
✓ Branch 14 taken 117655 times.
✓ Branch 15 taken 2253 times.
✓ Branch 16 taken 4925 times.
✓ Branch 17 taken 25 times.
✓ Branch 18 taken 28 times.
✓ Branch 19 taken 389 times.
✓ Branch 20 taken 2 times.
✓ Branch 21 taken 38 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✓ Branch 24 taken 168 times.
11178508 switch (command) {
2109 2635 case COM_INIT_DB: {
2110 LEX_STRING tmp;
2111 2635 thd->status_var.com_stat[SQLCOM_CHANGE_DB]++;
2112 2635 thd->convert_string(&tmp, system_charset_info,
2113 2635 com_data->com_init_db.db_name,
2114
1/2
✓ Branch 0 taken 2635 times.
✗ Branch 1 not taken.
2635 com_data->com_init_db.length, thd->charset());
2115
2116 2635 LEX_CSTRING tmp_cstr = {tmp.str, tmp.length};
2117
3/4
✓ Branch 0 taken 2635 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2614 times.
✓ Branch 3 taken 21 times.
2635 if (!mysql_change_db(thd, tmp_cstr, false)) {
2118
1/2
✓ Branch 0 taken 2614 times.
✗ Branch 1 not taken.
2614 query_logger.general_log_write(thd, command, thd->db().str,
2119 2614 thd->db().length);
2120
1/2
✓ Branch 0 taken 2614 times.
✗ Branch 1 not taken.
2614 my_ok(thd);
2121 }
2122 2635 break;
2123 }
2124 7125 case COM_REGISTER_SLAVE: {
2125 // TODO: access of protocol_classic should be removed
2126
5/8
✓ Branch 0 taken 7125 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7125 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7125 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 7041 times.
✓ Branch 7 taken 84 times.
7125 if (!register_replica(thd, thd->get_protocol_classic()->get_raw_packet(),
2127 thd->get_protocol_classic()->get_packet_length()))
2128
1/2
✓ Branch 0 taken 7041 times.
✗ Branch 1 not taken.
7041 my_ok(thd);
2129 7125 break;
2130 }
2131 1286 case COM_RESET_CONNECTION: {
2132 1286 thd->status_var.com_other++;
2133 #ifdef WITH_WSREP
2134
1/2
✓ Branch 0 taken 1286 times.
✗ Branch 1 not taken.
1286 wsrep_after_command_ignore_result(thd);
2135
1/2
✓ Branch 0 taken 1286 times.
✗ Branch 1 not taken.
1286 wsrep_close(thd);
2136 #endif /* WITH_WSREP */
2137
1/2
✓ Branch 0 taken 1286 times.
✗ Branch 1 not taken.
1286 thd->cleanup_connection();
2138 #ifdef WITH_WSREP
2139
1/2
✓ Branch 0 taken 1285 times.
✗ Branch 1 not taken.
1286 wsrep_open(thd);
2140
1/2
✓ Branch 0 taken 1286 times.
✗ Branch 1 not taken.
1285 wsrep_before_command(thd);
2141 #endif /* WITH_WSREP */
2142
1/2
✓ Branch 0 taken 1286 times.
✗ Branch 1 not taken.
1286 my_ok(thd);
2143 1286 break;
2144 }
2145 2157 case COM_CLONE: {
2146 2157 thd->status_var.com_other++;
2147
2148 /* Try loading clone plugin */
2149
1/2
✓ Branch 0 taken 2158 times.
✗ Branch 1 not taken.
4314 clone_cmd = new (thd->mem_root) Sql_cmd_clone();
2150
2151
6/8
✓ Branch 0 taken 2157 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2158 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 2153 times.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 2153 times.
2157 if (clone_cmd && clone_cmd->load(thd)) {
2152 5 clone_cmd = nullptr;
2153 }
2154
2155 2158 thd->lex->m_sql_cmd = clone_cmd;
2156 2158 thd->lex->sql_command = SQLCOM_CLONE;
2157
2158 2158 break;
2159 }
2160 442 case COM_SUBSCRIBE_GROUP_REPLICATION_STREAM: {
2161 442 Security_context *sctx = thd->security_context();
2162
1/2
✓ Branch 0 taken 442 times.
✗ Branch 1 not taken.
442 if (!sctx->has_global_grant(STRING_WITH_LEN("GROUP_REPLICATION_STREAM"))
2163
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 442 times.
442 .first) {
2164 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "");
2165 error = true;
2166 break;
2167 }
2168
2169
6/8
✓ Branch 0 taken 442 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 442 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 74 times.
✓ Branch 5 taken 368 times.
✓ Branch 6 taken 74 times.
✓ Branch 7 taken 368 times.
442 if (!error && get_gr_incoming_connection() == nullptr) {
2170
1/2
✓ Branch 0 taken 74 times.
✗ Branch 1 not taken.
74 my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
2171 74 error = true;
2172 74 break;
2173 }
2174
2175
1/2
✓ Branch 0 taken 368 times.
✗ Branch 1 not taken.
368 my_ok(thd);
2176
2177 368 break;
2178 }
2179 235 case COM_CHANGE_USER: {
2180 /*
2181 LOCK_thd_security_ctx protects the THD's security-context from
2182 inspection by SHOW PROCESSLIST while we're updating it. Nested
2183 acquiring of LOCK_thd_data is fine (see below).
2184 */
2185 235 MUTEX_LOCK(grd_secctx, &thd->LOCK_thd_security_ctx);
2186
2187 int auth_rc;
2188 235 thd->status_var.com_other++;
2189
2190 #ifdef WITH_WSREP
2191
1/2
✓ Branch 0 taken 235 times.
✗ Branch 1 not taken.
235 wsrep_after_command_ignore_result(thd);
2192
1/2
✓ Branch 0 taken 235 times.
✗ Branch 1 not taken.
235 wsrep_close(thd);
2193 #endif /* WITH_WSREP */
2194
2195
1/2
✓ Branch 0 taken 235 times.
✗ Branch 1 not taken.
235 thd->cleanup_connection();
2196
2197 #ifdef WITH_WSREP
2198
1/2
✓ Branch 0 taken 235 times.
✗ Branch 1 not taken.
235 wsrep_open(thd);
2199
1/2
✓ Branch 0 taken 235 times.
✗ Branch 1 not taken.
235 wsrep_before_command(thd);
2200 #endif /* WITH_WSREP */
2201
2202 USER_CONN *save_user_connect =
2203 235 const_cast<USER_CONN *>(thd->get_user_connect());
2204 235 LEX_CSTRING save_db = thd->db();
2205
1/2
✓ Branch 0 taken 235 times.
✗ Branch 1 not taken.
235 Security_context save_security_ctx(*(thd->security_context()));
2206
2207
1/2
✓ Branch 0 taken 235 times.
✗ Branch 1 not taken.
235 auth_rc = acl_authenticate(thd, COM_CHANGE_USER);
2208
1/2
✓ Branch 0 taken 235 times.
✗ Branch 1 not taken.
235 auth_rc |= mysql_audit_notify(
2209 thd, AUDIT_EVENT(MYSQL_AUDIT_CONNECTION_CHANGE_USER));
2210
2/2
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 170 times.
235 if (auth_rc) {
2211
1/2
✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
65 *thd->security_context() = save_security_ctx;
2212
1/2
✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
65 thd->set_user_connect(save_user_connect);
2213
1/2
✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
65 thd->reset_db(save_db);
2214
2215
1/2
✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
65 my_error(ER_ACCESS_DENIED_CHANGE_USER_ERROR, MYF(0),
2216
1/2
✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
65 thd->security_context()->user().str,
2217
1/2
✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
65 thd->security_context()->host_or_ip().str,
2218
4/6
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
65 (thd->password ? ER_THD(thd, ER_YES) : ER_THD(thd, ER_NO)));
2219 65 thd->killed = THD::KILL_CONNECTION;
2220 65 error = true;
2221 } else {
2222 #ifdef HAVE_PSI_THREAD_INTERFACE
2223 /* we've authenticated new user */
2224
1/2
✓ Branch 0 taken 170 times.
✗ Branch 1 not taken.
170 PSI_THREAD_CALL(notify_session_change_user)(thd->get_psi());
2225 #endif /* HAVE_PSI_THREAD_INTERFACE */
2226
2227
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 170 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
170 if (save_user_connect) decrease_user_connections(save_user_connect);
2228
1/2
✓ Branch 0 taken 170 times.
✗ Branch 1 not taken.
170 mysql_mutex_lock(&thd->LOCK_thd_data);
2229
1/2
✓ Branch 0 taken 170 times.
✗ Branch 1 not taken.
170 my_free(const_cast<char *>(save_db.str));
2230 170 save_db = NULL_CSTR;
2231
1/2
✓ Branch 0 taken 170 times.
✗ Branch 1 not taken.
170 mysql_mutex_unlock(&thd->LOCK_thd_data);
2232 }
2233 235 break;
2234 235 }
2235 5174 case COM_STMT_EXECUTE: {
2236 /* Clear possible warnings from the previous command */
2237
1/2
✓ Branch 0 taken 5174 times.
✗ Branch 1 not taken.
5174 thd->reset_for_next_command();
2238
2239 5174 Prepared_statement *stmt = nullptr;
2240
3/4
✓ Branch 0 taken 5174 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5165 times.
✓ Branch 3 taken 9 times.
5174 if (!mysql_stmt_precheck(thd, com_data, command, &stmt)) {
2241 5165 PS_PARAM *parameters = com_data->com_stmt_execute.parameters;
2242 5165 copy_bind_parameter_values(thd, parameters,
2243
1/2
✓ Branch 0 taken 5165 times.
✗ Branch 1 not taken.
5165 com_data->com_stmt_execute.parameter_count);
2244
2245 5165 mysqld_stmt_execute(thd, stmt, com_data->com_stmt_execute.has_new_types,
2246
1/2
✓ Branch 0 taken 5165 times.
✗ Branch 1 not taken.
5165 com_data->com_stmt_execute.open_cursor, parameters);
2247 #ifdef WITH_WSREP
2248
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5164 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
5165 if (WSREP_ON) {
2249
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 (void)wsrep_after_statement(thd);
2250 }
2251 #endif /* WITH_WSREP */
2252 5165 thd->bind_parameter_values = nullptr;
2253 5165 thd->bind_parameter_values_count = 0;
2254 }
2255 5174 break;
2256 }
2257 1815 case COM_STMT_FETCH: {
2258 /* Clear possible warnings from the previous command */
2259
1/2
✓ Branch 0 taken 1815 times.
✗ Branch 1 not taken.
1815 thd->reset_for_next_command();
2260
2261 1815 Prepared_statement *stmt = nullptr;
2262
3/4
✓ Branch 0 taken 1815 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1813 times.
✓ Branch 3 taken 2 times.
1815 if (!mysql_stmt_precheck(thd, com_data, command, &stmt))
2263
1/2
✓ Branch 0 taken 1813 times.
✗ Branch 1 not taken.
1813 mysqld_stmt_fetch(thd, stmt, com_data->com_stmt_fetch.num_rows);
2264
2265 1815 break;
2266 }
2267 496 case COM_STMT_SEND_LONG_DATA: {
2268 Prepared_statement *stmt;
2269 496 thd->get_stmt_da()->disable_status();
2270
3/4
✓ Branch 0 taken 496 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 492 times.
✓ Branch 3 taken 4 times.
496 if (!mysql_stmt_precheck(thd, com_data, command, &stmt))
2271 492 mysql_stmt_get_longdata(thd, stmt,
2272 492 com_data->com_stmt_send_long_data.param_number,
2273 492 com_data->com_stmt_send_long_data.longdata,
2274
1/2
✓ Branch 0 taken 492 times.
✗ Branch 1 not taken.
492 com_data->com_stmt_send_long_data.length);
2275 496 break;
2276 }
2277 4753 case COM_STMT_PREPARE: {
2278 /* Clear possible warnings from the previous command */
2279
1/2
✓ Branch 0 taken 4753 times.
✗ Branch 1 not taken.
4753 thd->reset_for_next_command();
2280 4753 Prepared_statement *stmt = nullptr;
2281
2282
2/20
✓ Branch 0 taken 4753 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4753 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
4753 DBUG_EXECUTE_IF("parser_stmt_to_error_log", {
2283 LogErr(INFORMATION_LEVEL, ER_PARSER_TRACE,
2284 com_data->com_stmt_prepare.query);
2285 });
2286
2/20
✓ Branch 0 taken 4753 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4753 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
4753 DBUG_EXECUTE_IF("parser_stmt_to_error_log_with_system_prio", {
2287 LogErr(SYSTEM_LEVEL, ER_PARSER_TRACE, com_data->com_stmt_prepare.query);
2288 });
2289
2290
2/4
✓ Branch 0 taken 4753 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4753 times.
✗ Branch 3 not taken.
4753 if (!mysql_stmt_precheck(thd, com_data, command, &stmt))
2291 4753 mysqld_stmt_prepare(thd, com_data->com_stmt_prepare.query,
2292
1/2
✓ Branch 0 taken 4753 times.
✗ Branch 1 not taken.
4753 com_data->com_stmt_prepare.length, stmt);
2293 4753 break;
2294 }
2295 4198 case COM_STMT_CLOSE: {
2296 4198 Prepared_statement *stmt = nullptr;
2297 4198 thd->get_stmt_da()->disable_status();
2298
3/4
✓ Branch 0 taken 4198 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4196 times.
✓ Branch 3 taken 2 times.
4198 if (!mysql_stmt_precheck(thd, com_data, command, &stmt))
2299
1/2
✓ Branch 0 taken 4196 times.
✗ Branch 1 not taken.
4196 mysqld_stmt_close(thd, stmt);
2300 4198 break;
2301 }
2302 57 case COM_STMT_RESET: {
2303 /* Clear possible warnings from the previous command */
2304
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 thd->reset_for_next_command();
2305
2306 57 Prepared_statement *stmt = nullptr;
2307
3/4
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 55 times.
✓ Branch 3 taken 2 times.
57 if (!mysql_stmt_precheck(thd, com_data, command, &stmt))
2308
1/2
✓ Branch 0 taken 55 times.
✗ Branch 1 not taken.
55 mysqld_stmt_reset(thd, stmt);
2309 57 break;
2310 }
2311 11022637 case COM_QUERY: {
2312
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11022637 times.
11022637 assert(thd->m_digest == nullptr);
2313 11022637 thd->m_digest = &thd->m_digest_state;
2314
1/2
✓ Branch 0 taken 11022589 times.
✗ Branch 1 not taken.
11022637 thd->m_digest->reset(thd->m_token_array, max_digest_length);
2315
2316
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11022934 times.
11022934 if (alloc_query(thd, com_data->com_query.query,
2317
1/2
✓ Branch 0 taken 11022934 times.
✗ Branch 1 not taken.
11022589 com_data->com_query.length))
2318 11020512 break; // fatal error is set
2319
2320
2/4
✓ Branch 0 taken 11022884 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11022886 times.
✗ Branch 3 not taken.
11022934 const char *packet_end = thd->query().str + thd->query().length;
2321
2322
2/2
✓ Branch 0 taken 226 times.
✓ Branch 1 taken 11022660 times.
11022886 if (opt_general_log_raw)
2323
1/2
✓ Branch 0 taken 226 times.
✗ Branch 1 not taken.
226 query_logger.general_log_write(thd, command, thd->query().str,
2324
2/4
✓ Branch 0 taken 226 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 226 times.
✗ Branch 3 not taken.
226 thd->query().length);
2325
2326
6/10
✓ Branch 0 taken 11022611 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11022710 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 190 times.
✓ Branch 5 taken 11022520 times.
✓ Branch 6 taken 190 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 190 times.
✗ Branch 9 not taken.
11022886 DBUG_PRINT("query", ("%-.4096s", thd->query().str));
2327
2328 #if defined(ENABLED_PROFILING)
2329
3/6
✓ Branch 0 taken 11022821 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11022844 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11022787 times.
✗ Branch 5 not taken.
11022710 thd->profiling->set_query_source(thd->query().str, thd->query().length);
2330 #endif
2331
2332
1/2
✓ Branch 0 taken 11022827 times.
✗ Branch 1 not taken.
11022787 const LEX_CSTRING orig_query = thd->query();
2333
2334
1/2
✓ Branch 0 taken 11022783 times.
✗ Branch 1 not taken.
11022827 Parser_state parser_state;
2335
5/8
✓ Branch 0 taken 11022829 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11022826 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11022653 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 11022652 times.
11022783 if (parser_state.init(thd, thd->query().str, thd->query().length)) break;
2336
2337 11022652 parser_state.m_input.m_has_digest = true;
2338
2339 // we produce digest if it's not explicitly turned off
2340 // by setting maximum digest length to zero
2341
3/4
✓ Branch 0 taken 11022466 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11022456 times.
✓ Branch 3 taken 10 times.
11022652 if (get_max_digest_length() != 0)
2342 11022456 parser_state.m_input.m_compute_digest = true;
2343
2344 // Initially, prepare and optimize the statement for the primary
2345 // storage engine. If an eligible secondary storage engine is
2346 // found, the statement may be reprepared for the secondary
2347 // storage engine later.
2348 11022466 const auto saved_secondary_engine = thd->secondary_engine_optimization();
2349 11022705 thd->set_secondary_engine_optimization(
2350 Secondary_engine_optimization::PRIMARY_TENTATIVELY);
2351
2352 11022721 copy_bind_parameter_values(thd, com_data->com_query.parameters,
2353
1/2
✓ Branch 0 taken 11022654 times.
✗ Branch 1 not taken.
11022721 com_data->com_query.parameter_count);
2354
2355 #ifdef WITH_WSREP
2356
3/4
✓ Branch 0 taken 162901 times.
✓ Branch 1 taken 10859753 times.
✓ Branch 2 taken 162901 times.
✗ Branch 3 not taken.
11022654 if (WSREP_ON) {
2357
2/4
✓ Branch 0 taken 162897 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 162897 times.
162901 if (wsrep_dispatch_sql_command(thd, thd->query().str,
2358
2/4
✓ Branch 0 taken 162901 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 162901 times.
✗ Branch 3 not taken.
162901 thd->query().length, &parser_state,
2359 false)) {
2360 WSREP_DEBUG("Deadlock error for: %s", thd->query().str);
2361 mysql_mutex_lock(&thd->LOCK_wsrep_thd);
2362 thd->killed = THD::NOT_KILLED;
2363 thd->wsrep_retry_counter = 0;
2364 mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
2365 goto dispatch_end;
2366 }
2367 } else {
2368
1/2
✓ Branch 0 taken 10857789 times.
✗ Branch 1 not taken.
10859753 dispatch_sql_command(thd, &parser_state, false);
2369 }
2370 #else
2371 dispatch_sql_command(thd, &parser_state, false);
2372 #endif /* WITH_WSREP */
2373
2374 // Check if the statement failed and needs to be restarted in
2375 // another storage engine.
2376 11020686 check_secondary_engine_statement(thd, &parser_state, orig_query.str,
2377
1/2
✓ Branch 0 taken 11020940 times.
✗ Branch 1 not taken.
11020686 orig_query.length);
2378
2379 11020940 thd->set_secondary_engine_optimization(saved_secondary_engine);
2380
2381
12/22
✓ Branch 0 taken 11020704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 446 times.
✓ Branch 3 taken 11020258 times.
✓ Branch 4 taken 446 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 446 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 446 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 446 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 446 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 446 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 446 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 446 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 446 times.
✗ Branch 21 not taken.
11020614 DBUG_EXECUTE_IF("parser_stmt_to_error_log", {
2382 LogErr(INFORMATION_LEVEL, ER_PARSER_TRACE, thd->query().str);
2383 });
2384
12/22
✓ Branch 0 taken 11020546 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 99 times.
✓ Branch 3 taken 11020447 times.
✓ Branch 4 taken 99 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 99 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 99 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 99 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 99 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 99 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 99 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 99 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 99 times.
✗ Branch 21 not taken.
11020704 DBUG_EXECUTE_IF("parser_stmt_to_error_log_with_system_prio", {
2385 LogErr(SYSTEM_LEVEL, ER_PARSER_TRACE, thd->query().str);
2386 });
2387
2388
6/6
✓ Branch 0 taken 11101100 times.
✓ Branch 1 taken 290 times.
✓ Branch 2 taken 81182 times.
✓ Branch 3 taken 11019918 times.
✓ Branch 4 taken 80932 times.
✓ Branch 5 taken 11020458 times.
11182652 while (!thd->killed && (parser_state.m_lip.found_semicolon != nullptr) &&
2389
3/4
✓ Branch 0 taken 81182 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80932 times.
✓ Branch 3 taken 250 times.
81182 !thd->is_error()) {
2390 /*
2391 Multiple queries exits, execute them individually
2392 */
2393 80932 const char *beginning_of_next_stmt = parser_state.m_lip.found_semicolon;
2394
2395 /* Finalize server status flags after executing a statement. */
2396
1/2
✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
80932 thd->update_slow_query_status();
2397
1/2
✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
80932 thd->send_statement_status();
2398
2399
1/2
✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
80932 const std::string &cn = Command_names::str_global(command);
2400
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 80932 times.
✓ Branch 2 taken 80932 times.
✗ Branch 3 not taken.
161864 mysql_audit_notify(thd, AUDIT_EVENT(MYSQL_AUDIT_GENERAL_STATUS),
2401 80932 thd->get_stmt_da()->is_error()
2402 ? thd->get_stmt_da()->mysql_errno()
2403 : 0,
2404 cn.c_str(), cn.length());
2405
2406 80932 size_t length =
2407 80932 static_cast<size_t>(packet_end - beginning_of_next_stmt);
2408
2409
1/2
✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
80932 log_slow_statement(thd);
2410
2411 80932 thd->reset_copy_status_var();
2412
2413 /* Remove garbage at start of query */
2414
3/4
✓ Branch 0 taken 96698 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15766 times.
✓ Branch 3 taken 80932 times.
193396 while (length > 0 &&
2415
2/2
✓ Branch 0 taken 15766 times.
✓ Branch 1 taken 80932 times.
96698 my_isspace(thd->charset(), *beginning_of_next_stmt)) {
2416 15766 beginning_of_next_stmt++;
2417 15766 length--;
2418 }
2419
2420 /* PSI end */
2421
1/2
✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
80932 MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
2422 80932 thd->m_statement_psi = nullptr;
2423 80932 thd->m_digest = nullptr;
2424
2425 /* SHOW PROFILE end */
2426 #if defined(ENABLED_PROFILING)
2427
1/2
✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
80932 thd->profiling->finish_current_query();
2428 #endif
2429
2430 /* SHOW PROFILE begin */
2431 #if defined(ENABLED_PROFILING)
2432
1/2
✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
80932 thd->profiling->start_new_query("continuing");
2433
1/2
✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
80932 thd->profiling->set_query_source(beginning_of_next_stmt, length);
2434 #endif
2435
2436
1/2
✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
80932 mysql_thread_set_secondary_engine(false);
2437
2438 /* PSI begin */
2439 80932 thd->m_digest = &thd->m_digest_state;
2440
1/2
✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
80932 thd->m_digest->reset(thd->m_token_array, max_digest_length);
2441
2442
1/2
✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
80932 thd->m_statement_psi = MYSQL_START_STATEMENT(
2443 &thd->m_statement_state, com_statement_info[command].m_key,
2444 thd->db().str, thd->db().length, thd->charset(), nullptr);
2445
1/2
✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
80932 THD_STAGE_INFO(thd, stage_starting);
2446
2447
1/2
✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
80932 thd->set_query(beginning_of_next_stmt, length);
2448
1/2
✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
80932 thd->set_query_id(next_query_id());
2449 /*
2450 Count each statement from the client.
2451 */
2452 80932 thd->status_var.questions++;
2453 #ifdef WITH_WSREP
2454
6/10
✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 80929 times.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 80929 times.
✗ Branch 9 not taken.
80932 if (!WSREP(thd)) thd->set_time(); /* Reset the query start time. */
2455
1/2
✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
80932 parser_state.reset(beginning_of_next_stmt, length);
2456 80932 thd->set_secondary_engine_optimization(
2457 Secondary_engine_optimization::PRIMARY_TENTATIVELY);
2458
2459
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 80929 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
80932 if (WSREP_ON) {
2460
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 if (wsrep_dispatch_sql_command(thd, beginning_of_next_stmt, length,
2461 &parser_state, false)) {
2462 WSREP_DEBUG("Deadlock error for: %s", thd->query().str);
2463 mysql_mutex_lock(&thd->LOCK_wsrep_thd);
2464 thd->killed = THD::NOT_KILLED;
2465 thd->wsrep_retry_counter = 0;
2466 mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
2467
2468 goto dispatch_end;
2469 }
2470 } else {
2471
1/2
✓ Branch 0 taken 80921 times.
✗ Branch 1 not taken.
80929 dispatch_sql_command(thd, &parser_state, false);
2472 }
2473 #else
2474 thd->set_time(); /* Reset the query start time. */
2475 parser_state.reset(beginning_of_next_stmt, length);
2476 thd->set_secondary_engine_optimization(
2477 Secondary_engine_optimization::PRIMARY_TENTATIVELY);
2478 /* TODO: set thd->lex->sql_command to SQLCOM_END here */
2479 dispatch_sql_command(thd, &parser_state, false);
2480 #endif /* WITH_WSREP */
2481
2482
1/2
✓ Branch 0 taken 80924 times.
✗ Branch 1 not taken.
80924 check_secondary_engine_statement(thd, &parser_state,
2483 beginning_of_next_stmt, length);
2484
2485 80924 thd->set_secondary_engine_optimization(saved_secondary_engine);
2486 }
2487
2488 11020458 thd->bind_parameter_values = nullptr;
2489 11020458 thd->bind_parameter_values_count = 0;
2490
2491 /* Need to set error to true for graceful shutdown */
2492
6/6
✓ Branch 0 taken 7779 times.
✓ Branch 1 taken 11012679 times.
✓ Branch 2 taken 7778 times.
✓ Branch 3 taken 218 times.
✓ Branch 4 taken 7778 times.
✓ Branch 5 taken 11012897 times.
11028454 if ((thd->lex->sql_command == SQLCOM_SHUTDOWN) &&
2493 7779 (thd->get_stmt_da()->is_ok()))
2494 7778 error = true;
2495
2496
5/8
✓ Branch 0 taken 11020817 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11020893 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 203 times.
✓ Branch 5 taken 11020690 times.
✓ Branch 6 taken 213 times.
✗ Branch 7 not taken.
11020675 DBUG_PRINT("info", ("query ready"));
2497 11020903 break;
2498
1/2
✓ Branch 0 taken 11020512 times.
✗ Branch 1 not taken.
11020904 }
2499 14 case COM_FIELD_LIST: // This isn't actually needed
2500 {
2501 char *fields;
2502 /* Locked closure of all tables */
2503 LEX_STRING table_name;
2504 LEX_STRING db;
2505
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 push_deprecated_warn(thd, "COM_FIELD_LIST",
2506 "SHOW COLUMNS FROM statement");
2507 /*
2508 SHOW statements should not add the used tables to the list of tables
2509 used in a transaction.
2510 */
2511
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 MDL_savepoint mdl_savepoint = thd->mdl_context.mdl_savepoint();
2512
2513 14 thd->status_var.com_stat[SQLCOM_SHOW_FIELDS]++;
2514
2/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
14 if (thd->copy_db_to(&db.str, &db.length)) break;
2515 14 thd->convert_string(&table_name, system_charset_info,
2516 14 (char *)com_data->com_field_list.table_name,
2517
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 com_data->com_field_list.table_name_length,
2518 thd->charset());
2519 Ident_name_check ident_check_status =
2520
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 check_table_name(table_name.str, table_name.length);
2521
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (ident_check_status == Ident_name_check::WRONG) {
2522 /* this is OK due to convert_string() null-terminating the string */
2523 my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name.str);
2524 break;
2525
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 } else if (ident_check_status == Ident_name_check::TOO_LONG) {
2526 my_error(ER_TOO_LONG_IDENT, MYF(0), table_name.str);
2527 break;
2528 }
2529
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 mysql_reset_thd_for_next_command(thd);
2530
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 lex_start(thd);
2531 /* Must be before we init the table list. */
2532
5/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 14 times.
14 if (lower_case_table_names && !is_infoschema_db(db.str, db.length))
2533 table_name.length = my_casedn_str(files_charset_info, table_name.str);
2534 14 TABLE_LIST table_list(db.str, db.length, table_name.str,
2535
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 table_name.length, table_name.str, TL_READ);
2536 /*
2537 Init TABLE_LIST members necessary when the undelrying
2538 table is view.
2539 */
2540 14 table_list.query_block = thd->lex->query_block;
2541 14 thd->lex->query_block->table_list.link_in_list(&table_list,
2542 &table_list.next_local);
2543 14 thd->lex->add_to_query_tables(&table_list);
2544
2545
3/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 12 times.
14 if (is_infoschema_db(table_list.db, table_list.db_length)) {
2546 ST_SCHEMA_TABLE *schema_table =
2547
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 find_schema_table(thd, table_list.alias);
2548
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (schema_table) table_list.schema_table = schema_table;
2549 }
2550
2551 14 if (!(fields =
2552
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 (char *)thd->memdup(com_data->com_field_list.query,
2553
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 com_data->com_field_list.query_length)))
2554 break;
2555 // Don't count end \0
2556
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 thd->set_query(fields, com_data->com_field_list.query_length - 1);
2557
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 query_logger.general_log_print(thd, command, "%s %s",
2558 table_list.table_name, fields);
2559
2560
2/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
14 if (open_temporary_tables(thd, &table_list)) break;
2561
2562
2/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
14 if (check_table_access(thd, SELECT_ACL, &table_list, true, UINT_MAX,
2563 false))
2564 break;
2565
2566 14 thd->lex->sql_command = SQLCOM_SHOW_FIELDS;
2567 // See comment in opt_trace_disable_if_no_security_context_access()
2568 14 Opt_trace_start ots(thd, &table_list, thd->lex->sql_command, nullptr,
2569
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 nullptr, 0, nullptr, nullptr);
2570
2571
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 mysqld_list_fields(thd, &table_list, fields);
2572
2573
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 thd->lex->cleanup(thd, true);
2574 /* No need to rollback statement transaction, it's not started. */
2575
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT));
2576
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 close_thread_tables(thd);
2577
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
2578
2579
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (thd->transaction_rollback_request) {
2580 /*
2581 Transaction rollback was requested since MDL deadlock was
2582 discovered while trying to open tables. Rollback transaction
2583 in all storage engines including binary log and release all
2584 locks.
2585 */
2586 trans_rollback_implicit(thd);
2587 thd->mdl_context.release_transactional_locks();
2588 }
2589
2590
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 thd->cleanup_after_query();
2591
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 thd->lex->destroy();
2592 14 break;
2593 14 }
2594 117655 case COM_QUIT:
2595 /* Prevent results of the form, "n>0 rows sent, 0 bytes sent" */
2596
1/2
✓ Branch 0 taken 117650 times.
✗ Branch 1 not taken.
117655 thd->set_sent_row_count(0);
2597 /* We don't calculate statistics for this command */
2598
1/2
✓ Branch 0 taken 117716 times.
✗ Branch 1 not taken.
117650 query_logger.general_log_print(thd, command, NullS);
2599 // Don't give 'abort' message
2600 // TODO: access of protocol_classic should be removed
2601
2/4
✓ Branch 0 taken 117716 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 117716 times.
✗ Branch 3 not taken.
117716 if (thd->is_classic_protocol())
2602
2/4
✓ Branch 0 taken 117716 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 117716 times.
✗ Branch 3 not taken.
117716 thd->get_protocol_classic()->get_net()->error = NET_ERROR_UNSET;
2603 117716 thd->get_stmt_da()->disable_status(); // Don't send anything back
2604 117428 error = true; // End server
2605 117428 break;
2606 2253 case COM_BINLOG_DUMP_GTID:
2607 // TODO: access of protocol_classic should be removed
2608
2/4
✓ Branch 0 taken 2253 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2251 times.
✗ Branch 3 not taken.
4506 error = com_binlog_dump_gtid(
2609
1/2
✓ Branch 0 taken 2253 times.
✗ Branch 1 not taken.
2253 thd, (char *)thd->get_protocol_classic()->get_raw_packet(),
2610 thd->get_protocol_classic()->get_packet_length());
2611 2251 break;
2612 4925 case COM_BINLOG_DUMP:
2613 // TODO: access of protocol_classic should be removed
2614
2/4
✓ Branch 0 taken 4925 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4922 times.
✗ Branch 3 not taken.
9850 error = com_binlog_dump(
2615
1/2
✓ Branch 0 taken 4925 times.
✗ Branch 1 not taken.
4925 thd, (char *)thd->get_protocol_classic()->get_raw_packet(),
2616 thd->get_protocol_classic()->get_packet_length());
2617 4922 break;
2618 25 case COM_REFRESH: {
2619 int not_used;
2620
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 push_deprecated_warn(thd, "COM_REFRESH", "FLUSH statement");
2621 /*
2622 Initialize thd->lex since it's used in many base functions, such as
2623 open_tables(). Otherwise, it remains uninitialized and may cause crash
2624 during execution of COM_REFRESH.
2625 */
2626
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 lex_start(thd);
2627
2628 25 thd->status_var.com_stat[SQLCOM_FLUSH]++;
2629 25 ulong options = (ulong)com_data->com_refresh.options;
2630
2/4
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 25 times.
25 if (trans_commit_implicit(thd)) break;
2631
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 thd->mdl_context.release_transactional_locks();
2632
2/4
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 25 times.
25 if (check_global_access(thd, RELOAD_ACL)) break;
2633
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 query_logger.general_log_print(thd, command, NullS);
2634 #ifndef NDEBUG
2635 25 bool debug_simulate = false;
2636
3/4
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 24 times.
25 DBUG_EXECUTE_IF("simulate_detached_thread_refresh",
2637 debug_simulate = true;);
2638
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 24 times.
25 if (debug_simulate) {
2639 /*
2640 Simulate a reload without a attached thread session.
2641 Provides a environment similar to that of when the
2642 server receives a SIGHUP signal and reloads caches
2643 and flushes tables.
2644 */
2645 bool res;
2646
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 current_thd = nullptr;
2647
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 res = handle_reload_request(nullptr, options | REFRESH_FAST, nullptr,
2648 &not_used);
2649
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 current_thd = thd;
2650
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (res) break;
2651 } else
2652 #endif
2653
2/4
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
24 if (handle_reload_request(thd, options, (TABLE_LIST *)nullptr,
2654 &not_used))
2655 break;
2656
2/4
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 25 times.
25 if (trans_commit_implicit(thd)) break;
2657
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 close_thread_tables(thd);
2658
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 thd->mdl_context.release_transactional_locks();
2659
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 thd->lex->destroy();
2660
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 my_ok(thd);
2661 25 break;
2662 }
2663 28 case COM_STATISTICS: {
2664 System_status_var current_global_status_var;
2665 ulong uptime;
2666 size_t length [[maybe_unused]];
2667 ulonglong queries_per_second1000;
2668 char buff[250];
2669 28 size_t buff_len = sizeof(buff);
2670
2671
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 query_logger.general_log_print(thd, command, NullS);
2672 28 thd->status_var.com_stat[SQLCOM_SHOW_STATUS]++;
2673
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 mysql_mutex_lock(&LOCK_status);
2674
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 calc_sum_of_all_status(&current_global_status_var);
2675
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 mysql_mutex_unlock(&LOCK_status);
2676
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 if (!(uptime = (ulong)(thd->query_start_in_secs() - server_start_time)))
2677 queries_per_second1000 = 0;
2678 else
2679 28 queries_per_second1000 = thd->query_id * 1000LL / uptime;
2680
2681 84 length = snprintf(buff, buff_len - 1,
2682 "Uptime: %lu Threads: %d Questions: %lu "
2683 "Slow queries: %llu Opens: %llu Flush tables: %lu "
2684 "Open tables: %u Queries per second avg: %u.%03u",
2685 28 uptime, (int)thd_manager->get_thd_count(),
2686 28 (ulong)thd->query_id,
2687 current_global_status_var.long_query_count,
2688 current_global_status_var.opened_tables,
2689 refresh_version, table_cache_manager.cached_tables(),
2690 28 (uint)(queries_per_second1000 / 1000),
2691
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 (uint)(queries_per_second1000 % 1000));
2692 // TODO: access of protocol_classic should be removed.
2693 // should be rewritten using store functions
2694
3/6
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 28 times.
28 if (thd->get_protocol_classic()->write(pointer_cast<const uchar *>(buff),
2695 length))
2696 break;
2697
2/4
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 28 times.
28 if (thd->get_protocol()->flush()) break;
2698 28 thd->get_stmt_da()->disable_status();
2699 28 break;
2700 }
2701 389 case COM_PING:
2702 389 thd->status_var.com_other++;
2703
1/2
✓ Branch 0 taken 389 times.
✗ Branch 1 not taken.
389 my_ok(thd); // Tell client we are alive
2704 389 break;
2705 2 case COM_PROCESS_INFO:
2706 bool global_access;
2707 LEX_CSTRING db_saved;
2708 2 thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]++;
2709
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 push_deprecated_warn(thd, "COM_PROCESS_INFO",
2710 "SHOW PROCESSLIST statement");
2711
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 global_access = (check_global_access(thd, PROCESS_ACL) == 0);
2712
3/8
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
2 if (!thd->security_context()->priv_user().str[0] && !global_access) break;
2713
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 query_logger.general_log_print(thd, command, NullS);
2714 2 db_saved = thd->db();
2715
2716
2/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2 DBUG_EXECUTE_IF("force_db_name_to_null", thd->reset_db(NULL_CSTR););
2717
2718
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 mysqld_list_processes(
2719 thd, global_access ? NullS : thd->security_context()->priv_user().str,
2720 false, false);
2721
2722
2/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2 DBUG_EXECUTE_IF("force_db_name_to_null", thd->reset_db(db_saved););
2723 2 break;
2724 38 case COM_PROCESS_KILL: {
2725
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 push_deprecated_warn(thd, "COM_PROCESS_KILL",
2726 "KILL CONNECTION/QUERY statement");
2727
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (thd_manager->get_thread_id() & (~0xfffffffful))
2728 my_error(ER_DATA_OUT_OF_RANGE, MYF(0), "thread_id", "mysql_kill()");
2729 else {
2730 38 thd->status_var.com_stat[SQLCOM_KILL]++;
2731
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 sql_kill(thd, com_data->com_kill.id, false);
2732 }
2733 38 break;
2734 }
2735 case COM_SET_OPTION: {
2736 thd->status_var.com_stat[SQLCOM_SET_OPTION]++;
2737
2738 switch (com_data->com_set_option.opt_command) {
2739 case (int)MYSQL_OPTION_MULTI_STATEMENTS_ON:
2740 // TODO: access of protocol_classic should be removed
2741 thd->get_protocol_classic()->add_client_capability(
2742 CLIENT_MULTI_STATEMENTS);
2743 my_eof(thd);
2744 break;
2745 case (int)MYSQL_OPTION_MULTI_STATEMENTS_OFF:
2746 thd->get_protocol_classic()->remove_client_capability(
2747 CLIENT_MULTI_STATEMENTS);
2748 my_eof(thd);
2749 break;
2750 default:
2751 my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
2752 break;
2753 }
2754 break;
2755 }
2756 1 case COM_DEBUG:
2757 1 thd->status_var.com_other++;
2758
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (check_global_access(thd, SUPER_ACL)) break; /* purecov: inspected */
2759
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 query_logger.general_log_print(thd, command, NullS);
2760
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_eof(thd);
2761 #ifdef WITH_LOCK_ORDER
2762 LO_dump();
2763 #endif /* WITH_LOCK_ORDER */
2764 1 break;
2765 168 case COM_SLEEP:
2766 case COM_CONNECT: // Impossible here
2767 case COM_TIME: // Impossible from client
2768 case COM_DELAYED_INSERT: // INSERT DELAYED has been removed.
2769 case COM_END:
2770 default:
2771
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
168 my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
2772 4 break;
2773 }
2774
2775 #ifdef WITH_WSREP
2776 11175922 dispatch_end:
2777 /*
2778 BF aborted before sending response back to client
2779 */
2780
2/2
✓ Branch 0 taken 2872 times.
✓ Branch 1 taken 11173523 times.
11175922 if (thd->killed == THD::KILL_QUERY) {
2781
1/24
✗ Branch 0 not taken.
✓ Branch 1 taken 2872 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
2872 WSREP_DEBUG("THD is killed at dispatch_end");
2782 }
2783
1/2
✓ Branch 0 taken 11176288 times.
✗ Branch 1 not taken.
11176395 wsrep_after_command_before_result(thd);
2784
5/6
✓ Branch 0 taken 706 times.
✓ Branch 1 taken 11176316 times.
✓ Branch 2 taken 706 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 706 times.
✓ Branch 5 taken 11176316 times.
11176994 if (wsrep_current_error(thd) &&
2785
3/6
✓ Branch 0 taken 706 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 706 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 706 times.
✗ Branch 5 not taken.
706 !(command == COM_STMT_PREPARE || command == COM_STMT_FETCH ||
2786 command == COM_STMT_SEND_LONG_DATA || command == COM_STMT_CLOSE)) {
2787 /* todo: Pass wsrep client state current error to override */
2788
1/2
✓ Branch 0 taken 705 times.
✗ Branch 1 not taken.
706 wsrep_override_error(thd, wsrep_current_error(thd),
2789 wsrep_current_error_status(thd));
2790
1/2
✓ Branch 0 taken 176 times.
✗ Branch 1 not taken.
705 WSREP_LOG_THD(thd, "leave");
2791 }
2792
2793
6/8
✗ Branch 0 not taken.
✓ Branch 1 taken 11176492 times.
✓ Branch 2 taken 11008931 times.
✓ Branch 3 taken 167561 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 167561 times.
✓ Branch 6 taken 5145 times.
✓ Branch 7 taken 162416 times.
11176492 if (WSREP(thd)) {
2794 /* wsrep BF abort in query exec phase */
2795
1/2
✓ Branch 0 taken 162417 times.
✗ Branch 1 not taken.
162416 mysql_mutex_lock(&thd->LOCK_wsrep_thd);
2796 162417 do_end_of_statement =
2797
3/4
✓ Branch 0 taken 162417 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 162402 times.
324834 !(thd->wsrep_trx().state() != wsrep::transaction::s_replaying &&
2798 162417 !thd->killed);
2799
2800
1/2
✓ Branch 0 taken 162259 times.
✗ Branch 1 not taken.
162417 mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
2801 }
2802
2803 #endif /* WITH_WSREP */
2804
2805 11014076 done:
2806
3/4
✓ Branch 0 taken 44703 times.
✓ Branch 1 taken 11131637 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 44703 times.
11176340 assert(thd->open_tables == nullptr ||
2807 (thd->locked_tables_mode == LTM_LOCK_TABLES));
2808
2809 /* Update user statistics only if at least one timer was initialized */
2810
5/6
✓ Branch 0 taken 11174549 times.
✓ Branch 1 taken 1791 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11174649 times.
✓ Branch 4 taken 1691 times.
✓ Branch 5 taken 11174649 times.
11176340 if (unlikely(start_busy_usecs > 0.0 || start_cpu_nsecs > 0.0)) {
2811 1691 userstat_finish_timer(start_busy_usecs, start_cpu_nsecs, &thd->busy_time,
2812 1691 &thd->cpu_time);
2813 /* Updates THD stats and the global user stats. */
2814 1691 thd->update_stats(true);
2815
1/2
✓ Branch 0 taken 1691 times.
✗ Branch 1 not taken.
1691 update_global_user_stats(thd, true, my_getsystime());
2816 }
2817
2818 /* Finalize server status flags after executing a command. */
2819
1/2
✓ Branch 0 taken 11177227 times.
✗ Branch 1 not taken.
11176340 thd->update_slow_query_status();
2820
3/4
✓ Branch 0 taken 6129 times.
✓ Branch 1 taken 11171111 times.
✓ Branch 2 taken 6128 times.
✗ Branch 3 not taken.
11177227 if (thd->killed) thd->send_kill_message();
2821
1/2
✓ Branch 0 taken 11176908 times.
✗ Branch 1 not taken.
11177239 thd->send_statement_status();
2822
2823 /* After sending response, switch to clone protocol */
2824
2/2
✓ Branch 0 taken 2153 times.
✓ Branch 1 taken 11174755 times.
11176908 if (clone_cmd != nullptr) {
2825
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2153 times.
2153 assert(command == COM_CLONE);
2826
1/2
✓ Branch 0 taken 2153 times.
✗ Branch 1 not taken.
2153 error = clone_cmd->execute_server(thd);
2827 }
2828
2829
4/4
✓ Branch 0 taken 442 times.
✓ Branch 1 taken 11176466 times.
✓ Branch 2 taken 368 times.
✓ Branch 3 taken 74 times.
11176908 if (command == COM_SUBSCRIBE_GROUP_REPLICATION_STREAM && !error) {
2830 368 call_gr_incoming_connection_cb(
2831 368 thd, thd->active_vio->mysql_socket.fd,
2832
1/2
✓ Branch 0 taken 368 times.
✗ Branch 1 not taken.
368 thd->active_vio->ssl_arg ? static_cast<SSL *>(thd->active_vio->ssl_arg)
2833 : nullptr);
2834 }
2835
2836 #ifdef WITH_WSREP
2837
2/2
✓ Branch 0 taken 11014225 times.
✓ Branch 1 taken 162683 times.
11176908 if (do_end_of_statement) {
2838 #endif /* WITH_WSREP */
2839
1/2
✓ Branch 0 taken 11014816 times.
✗ Branch 1 not taken.
11014225 thd->rpl_thd_ctx.session_gtids_ctx().notify_after_response_packet(thd);
2840 #ifdef WITH_WSREP
2841 }
2842 #endif /* WITH_WSREP */
2843
2844
7/8
✓ Branch 0 taken 11177156 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11083693 times.
✓ Branch 3 taken 93463 times.
✓ Branch 4 taken 11082943 times.
✓ Branch 5 taken 616 times.
✓ Branch 6 taken 11082966 times.
✓ Branch 7 taken 94056 times.
11177499 if (!thd->is_error() && !thd->killed)
2845
1/2
✓ Branch 0 taken 11082317 times.
✗ Branch 1 not taken.
11082966 mysql_audit_notify(thd, AUDIT_EVENT(MYSQL_AUDIT_GENERAL_RESULT), 0, nullptr,
2846 0);
2847
2848
1/2
✓ Branch 0 taken 11176219 times.
✗ Branch 1 not taken.
11176373 const std::string &cn = Command_names::str_global(command);
2849
3/4
✓ Branch 0 taken 93471 times.
✓ Branch 1 taken 11083281 times.
✓ Branch 2 taken 11177147 times.
✗ Branch 3 not taken.
22446442 mysql_audit_notify(
2850 thd, AUDIT_EVENT(MYSQL_AUDIT_GENERAL_STATUS),
2851 11270111 thd->get_stmt_da()->is_error() ? thd->get_stmt_da()->mysql_errno() : 0,
2852 cn.c_str(), cn.length());
2853
2854 /* command_end is informational only. The plugin cannot abort
2855 execution of the command at this point. */
2856
1/2
✓ Branch 0 taken 11176735 times.
✗ Branch 1 not taken.
11177147 mysql_audit_notify(thd, AUDIT_EVENT(MYSQL_AUDIT_COMMAND_END), command,
2857 cn.c_str());
2858
2859
1/2
✓ Branch 0 taken 11177020 times.
✗ Branch 1 not taken.
11176735 log_slow_statement(thd);
2860
2861
1/2
✓ Branch 0 taken 11176396 times.
✗ Branch 1 not taken.
11177020 THD_STAGE_INFO(thd, stage_cleaning_up);
2862
2/2
✓ Branch 0 taken 162406 times.
✓ Branch 1 taken 11013990 times.
11176396 if (thd->lex->sql_command == SQLCOM_CREATE_TABLE) {
2863
3/4
✓ Branch 0 taken 162373 times.
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 162373 times.
✗ Branch 3 not taken.
162406 DEBUG_SYNC(thd, "dispatch_create_table_command_before_thd_root_free");
2864 }
2865
2866
2/2
✓ Branch 0 taken 2872 times.
✓ Branch 1 taken 11173560 times.
11176396 if (thd->killed == THD::KILL_QUERY) {
2867 2872 thd->killed = THD::NOT_KILLED;
2868 }
2869
2870
1/2
✓ Branch 0 taken 11177362 times.
✗ Branch 1 not taken.
11176432 thd->reset_query();
2871
1/2
✓ Branch 0 taken 11176566 times.
✗ Branch 1 not taken.
11177362 thd->set_command(COM_SLEEP);
2872 11176566 thd->set_proc_info(nullptr);
2873 11176743 thd->lex->sql_command = SQLCOM_END;
2874
2875 /* Performance Schema Interface instrumentation, end */
2876
1/2
✓ Branch 0 taken 11175738 times.
✗ Branch 1 not taken.
11176743 MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
2877 11175738 thd->m_statement_psi = nullptr;
2878 11175738 thd->m_digest = nullptr;
2879
1/2
✓ Branch 0 taken 11177394 times.
✗ Branch 1 not taken.
11175738 thd->reset_query_for_display();
2880
2881 /* Prevent rewritten query from getting "stuck" in SHOW PROCESSLIST. */
2882
1/2
✓ Branch 0 taken 11176848 times.
✗ Branch 1 not taken.
11177394 thd->reset_rewritten_query();
2883
2884 11176848 thd_manager->dec_thread_running();
2885
2886 /* Freeing the memroot will leave the THD::work_part_info invalid. */
2887 11177121 thd->work_part_info = nullptr;
2888
2889 /*
2890 If we've allocated a lot of memory (compared to the default preallocation
2891 size = 8192; note that we don't actually preallocate anymore), free
2892 it so that one big query won't cause us to hold on to a lot of RAM forever.
2893 If not, keep the last block so that the next query will hopefully be able to
2894 run without allocating memory from the OS.
2895
2896 The factor 5 is pretty much arbitrary, but ends up allowing three
2897 allocations (1 + 1.5 + 1.5²) under the current allocation policy.
2898 */
2899 11177121 constexpr size_t kPreallocSz = 40960;
2900
2/2
✓ Branch 0 taken 10523457 times.
✓ Branch 1 taken 652430 times.
11177121 if (thd->mem_root->allocated_size() < kPreallocSz)
2901
1/2
✓ Branch 0 taken 10524559 times.
✗ Branch 1 not taken.
10523457 thd->mem_root->ClearForReuse();
2902 else
2903
1/2
✓ Branch 0 taken 652430 times.
✗ Branch 1 not taken.
652430 thd->mem_root->Clear();
2904
2905 /* SHOW PROFILE instrumentation, end */
2906 #if defined(ENABLED_PROFILING)
2907
1/2
✓ Branch 0 taken 11177020 times.
✗ Branch 1 not taken.
11176989 thd->profiling->finish_current_query();
2908 #endif
2909
2910 11176543 return error;
2911 11177020 }
2912
2913 /**
2914 Shutdown the mysqld server.
2915
2916 @param thd Thread (session) context.
2917 @param level Shutdown level.
2918
2919 @retval
2920 true success
2921 @retval
2922 false When user has insufficient privilege or unsupported
2923 shutdown level
2924
2925 */
2926
2927 7781 bool shutdown(THD *thd, enum mysql_enum_shutdown_level level) {
2928
1/2
✓ Branch 0 taken 7781 times.
✗ Branch 1 not taken.
7781 DBUG_TRACE;
2929 7781 bool res = false;
2930 7781 thd->lex->no_write_to_binlog = true;
2931
2932
2/4
✓ Branch 0 taken 7781 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7781 times.
7781 if (check_global_access(thd, SHUTDOWN_ACL))
2933 goto error; /* purecov: inspected */
2934
2935
1/2
✓ Branch 0 taken 7781 times.
✗ Branch 1 not taken.
7781 if (level == SHUTDOWN_DEFAULT)
2936 7781 level = SHUTDOWN_WAIT_ALL_BUFFERS; // soon default will be configurable
2937 else if (level != SHUTDOWN_WAIT_ALL_BUFFERS) {
2938 my_error(ER_NOT_SUPPORTED_YET, MYF(0), "this shutdown level");
2939 goto error;
2940 ;
2941 }
2942
2943
1/2
✓ Branch 0 taken 7781 times.
✗ Branch 1 not taken.
7781 my_ok(thd);
2944
2945
9/18
✓ Branch 0 taken 7781 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7781 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7781 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 7781 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7781 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 7781 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 7781 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 7781 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 7781 times.
✗ Branch 17 not taken.
7781 LogErr(SYSTEM_LEVEL, ER_SERVER_SHUTDOWN_INFO,
2946 thd->security_context()->user().str, server_version,
2947 MYSQL_COMPILATION_COMMENT_SERVER);
2948
2949
5/8
✓ Branch 0 taken 7781 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7781 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 7780 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
7781 DBUG_PRINT("quit", ("Got shutdown command for level %u", level));
2950
1/2
✓ Branch 0 taken 7781 times.
✗ Branch 1 not taken.
7781 query_logger.general_log_print(thd, COM_QUERY, NullS);
2951
1/2
✓ Branch 0 taken 7781 times.
✗ Branch 1 not taken.
7781 kill_mysql();
2952 7781 res = true;
2953
2954 7781 error:
2955 7781 return res;
2956 7781 }
2957
2958 /**
2959 Create a TABLE_LIST object for an INFORMATION_SCHEMA table.
2960
2961 This function is used in the parser to convert a SHOW or DESCRIBE
2962 table_name command to a SELECT from INFORMATION_SCHEMA.
2963 It prepares a Query_block and a TABLE_LIST object to represent the
2964 given command as a SELECT parse tree.
2965
2966 @param thd thread handle
2967 @param lex current lex
2968 @param table_ident table alias if it's used
2969 @param schema_table_idx the type of the INFORMATION_SCHEMA table to be
2970 created
2971
2972 @note
2973 Due to the way this function works with memory and LEX it cannot
2974 be used outside the parser (parse tree transformations outside
2975 the parser break PS and SP).
2976
2977 @retval
2978 0 success
2979 @retval
2980 1 out of memory or SHOW commands are not allowed
2981 in this version of the server.
2982 */
2983
2984 362 int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
2985 enum enum_schema_tables schema_table_idx) {
2986 362 Query_block *schema_query_block = nullptr;
2987
1/2
✓ Branch 0 taken 362 times.
✗ Branch 1 not taken.
362 DBUG_TRACE;
2988
2989
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 330 times.
362 switch (schema_table_idx) {
2990 case SCH_TMP_TABLE_COLUMNS:
2991 case SCH_TMP_TABLE_KEYS: {
2992 assert(table_ident);
2993 TABLE_LIST **query_tables_last = lex->query_tables_last;
2994 if ((schema_query_block = lex->new_empty_query_block()) == nullptr)
2995 return 1; /* purecov: inspected */
2996 if (!schema_query_block->add_table_to_list(thd, table_ident, nullptr, 0,
2997 TL_READ, MDL_SHARED_READ))
2998 return 1;
2999 lex->query_tables_last = query_tables_last;
3000 break;
3001 }
3002 26 case SCH_PROFILES:
3003 /*
3004 Mark this current profiling record to be discarded. We don't
3005 wish to have SHOW commands show up in profiling->
3006 */
3007 #if defined(ENABLED_PROFILING)
3008
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 thd->profiling->discard_current_query();
3009 #endif
3010 26 break;
3011 6 case SCH_USER_STATS:
3012 case SCH_CLIENT_STATS:
3013 case SCH_THREAD_STATS:
3014
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 if (check_global_access(thd, SUPER_ACL | PROCESS_ACL)) return 1;
3015 case SCH_TABLE_STATS:
3016 case SCH_INDEX_STATS:
3017 case SCH_OPTIMIZER_TRACE:
3018 case SCH_OPEN_TABLES:
3019 case SCH_ENGINES:
3020 case SCH_USER_PRIVILEGES:
3021 case SCH_SCHEMA_PRIVILEGES:
3022 case SCH_TABLE_PRIVILEGES:
3023 case SCH_COLUMN_PRIVILEGES:
3024 case SCH_TEMPORARY_TABLES:
3025 case SCH_GLOBAL_TEMPORARY_TABLES:
3026 default:
3027 336 break;
3028 }
3029
3030 362 Query_block *query_block = lex->current_query_block();
3031
2/4
✓ Branch 0 taken 362 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 362 times.
362 if (make_schema_query_block(thd, query_block, schema_table_idx)) {
3032 return 1;
3033 }
3034 362 TABLE_LIST *table_list = query_block->table_list.first;
3035 362 table_list->schema_query_block = schema_query_block;
3036 362 table_list->schema_table_reformed = true;
3037 362 return 0;
3038 362 }
3039
3040 /**
3041 Read query from packet and store in thd->query.
3042 Used in COM_QUERY and COM_STMT_PREPARE.
3043
3044 Sets the following THD variables:
3045 - query
3046 - query_length
3047
3048 @retval
3049 false ok
3050 @retval
3051 true error; In this case thd->fatal_error is set
3052 */
3053
3054 19023938 bool alloc_query(THD *thd, const char *packet, size_t packet_length) {
3055 /* Remove garbage at start and end of query */
3056
5/6
✓ Branch 0 taken 19041084 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16887 times.
✓ Branch 3 taken 19024406 times.
✓ Branch 4 taken 16887 times.
✓ Branch 5 taken 19024147 times.
19040825 while (packet_length > 0 && my_isspace(thd->charset(), packet[0])) {
3057 16887 packet++;
3058 16887 packet_length--;
3059 }
3060 19024147 const char *pos = packet + packet_length; // Point at end null
3061
3/4
✓ Branch 0 taken 23909040 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4884327 times.
✓ Branch 3 taken 19024206 times.
47817573 while (packet_length > 0 &&
3062
4/4
✓ Branch 0 taken 21744095 times.
✓ Branch 1 taken 2164945 times.
✓ Branch 2 taken 2719383 times.
✓ Branch 3 taken 19024771 times.
23909040 (pos[-1] == ';' || my_isspace(thd->charset(), pos[-1]))) {
3063 4884327 pos--;
3064 4884327 packet_length--;
3065 }
3066
3067 19024206 char *query = static_cast<char *>(thd->alloc(packet_length + 1));
3068
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19024594 times.
19024594 if (!query) return true;
3069 19024594 memcpy(query, packet, packet_length);
3070 19024594 query[packet_length] = '\0';
3071
3072 19024594 thd->set_query(query, packet_length);
3073
3074 19025694 return false;
3075 }
3076
3077 37130 static bool sp_process_definer(THD *thd) {
3078
1/2
✓ Branch 0 taken 37130 times.
✗ Branch 1 not taken.
37130 DBUG_TRACE;
3079
3080 37130 LEX *lex = thd->lex;
3081
3082 /*
3083 If the definer is not specified, this means that CREATE-statement missed
3084 DEFINER-clause. DEFINER-clause can be missed in two cases:
3085
3086 - The user submitted a statement w/o the clause. This is a normal
3087 case, we should assign CURRENT_USER as definer.
3088
3089 - Our slave received an updated from the master, that does not
3090 replicate definer for stored routines. We should also assign
3091 CURRENT_USER as definer here, but also we should mark this routine
3092 as NON-SUID. This is essential for the sake of backward
3093 compatibility.
3094
3095 The problem is the slave thread is running under "special" user (@),
3096 that actually does not exist. In the older versions we do not fail
3097 execution of a stored routine if its definer does not exist and
3098 continue the execution under the authorization of the invoker
3099 (BUG#13198). And now if we try to switch to slave-current-user (@),
3100 we will fail.
3101
3102 Actually, this leads to the inconsistent state of master and
3103 slave (different definers, different SUID behaviour), but it seems,
3104 this is the best we can do.
3105 */
3106
3107
2/2
✓ Branch 0 taken 15973 times.
✓ Branch 1 taken 21157 times.
37130 if (!lex->definer) {
3108
1/2
✓ Branch 0 taken 15973 times.
✗ Branch 1 not taken.
15973 Prepared_stmt_arena_holder ps_arena_holder(thd);
3109
3110
1/2
✓ Branch 0 taken 15973 times.
✗ Branch 1 not taken.
15973 lex->definer = create_default_definer(thd);
3111
3112 /* Error has been already reported. */
3113
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15973 times.
15973 if (lex->definer == nullptr) return true;
3114
3115
4/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 15923 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 42 times.
15973 if (thd->slave_thread && lex->sphead)
3116 8 lex->sphead->m_chistics->suid = SP_IS_NOT_SUID;
3117
1/2
✓ Branch 0 taken 15973 times.
✗ Branch 1 not taken.
15973 } else {
3118 /*
3119 If the specified definer differs from the current user, we
3120 should check that the current user has a set_user_id privilege
3121 (in order to create a stored routine under another user one must
3122 have a set_user_id privilege).
3123 */
3124 21157 Security_context *sctx = thd->security_context();
3125 42314 if ((strcmp(lex->definer->user.str,
3126
5/6
✓ Branch 0 taken 21157 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 158 times.
✓ Branch 3 taken 20999 times.
✓ Branch 4 taken 20999 times.
✓ Branch 5 taken 158 times.
21315 thd->security_context()->priv_user().str) ||
3127
3/6
✓ Branch 0 taken 158 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 158 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 158 times.
158 my_strcasecmp(system_charset_info, lex->definer->host.str,
3128 thd->security_context()->priv_host().str))) {
3129
8/16
✓ Branch 0 taken 20999 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20999 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 20984 times.
✓ Branch 6 taken 20999 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 20999 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4 times.
✓ Branch 11 taken 20995 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
21014 if (!(sctx->check_access(SUPER_ACL) ||
3130
3/4
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 11 times.
15 sctx->has_global_grant(STRING_WITH_LEN("SET_USER_ID")).first)) {
3131 4 thd->diff_access_denied_errors++;
3132
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0),
3133 "SUPER or SET_USER_ID");
3134 4 return true;
3135 }
3136
4/6
✓ Branch 0 taken 20995 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20995 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 20991 times.
20995 if (sctx->can_operate_with({lex->definer}, consts::system_user))
3137 4 return true;
3138 }
3139 }
3140
3141 /* Check that the specified definer exists. Emit a warning if not. */
3142
3143
3/4
✓ Branch 0 taken 37122 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9524 times.
✓ Branch 3 taken 27598 times.
37122 if (!is_acl_user(thd, lex->definer->host.str, lex->definer->user.str)) {
3144
1/2
✓ Branch 0 taken 9524 times.
✗ Branch 1 not taken.
9524 push_warning_printf(thd, Sql_condition::SL_NOTE, ER_NO_SUCH_USER,
3145 9524 ER_THD(thd, ER_NO_SUCH_USER), lex->definer->user.str,
3146
1/2
✓ Branch 0 taken 9524 times.
✗ Branch 1 not taken.
9524 lex->definer->host.str);
3147 }
3148
3149 37122 return false;
3150 37130 }
3151
3152 /**
3153 Auxiliary call that opens and locks tables for LOCK TABLES statement
3154 and initializes the list of locked tables.
3155
3156 @param thd Thread context.
3157 @param tables List of tables to be locked.
3158
3159 @return false in case of success, true in case of error.
3160 */
3161
3162 2619 static bool lock_tables_open_and_lock_tables(THD *thd, TABLE_LIST *tables) {
3163 2619 Lock_tables_prelocking_strategy lock_tables_prelocking_strategy;
3164 2619 MDL_deadlock_and_lock_abort_error_handler deadlock_handler;
3165
1/2
✓ Branch 0 taken 2619 times.
✗ Branch 1 not taken.
2619 MDL_savepoint mdl_savepoint = thd->mdl_context.mdl_savepoint();
3166 uint counter;
3167 TABLE_LIST *table;
3168
3169 2619 thd->in_lock_tables = true;
3170
3171 2620 retry:
3172
3173
3/4
✓ Branch 0 taken 2620 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
✓ Branch 3 taken 2579 times.
2620 if (open_tables(thd, &tables, &counter, 0, &lock_tables_prelocking_strategy))
3174 41 goto err;
3175
3176 2579 deadlock_handler.init();
3177
1/2
✓ Branch 0 taken 2579 times.
✗ Branch 1 not taken.
2579 thd->push_internal_handler(&deadlock_handler);
3178
3179
2/2
✓ Branch 0 taken 11905 times.
✓ Branch 1 taken 2578 times.
14483 for (table = tables; table; table = table->next_global) {
3180
2/2
✓ Branch 0 taken 8564 times.
✓ Branch 1 taken 3341 times.
11905 if (!table->is_placeholder()) {
3181
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 8538 times.
8564 if (table->table->s->tmp_table) {
3182 /*
3183 We allow to change temporary tables even if they were locked for read
3184 by LOCK TABLES. To avoid a discrepancy between lock acquired at LOCK
3185 TABLES time and by the statement which is later executed under LOCK
3186 TABLES we ensure that for temporary tables we always request a write
3187 lock (such discrepancy can cause problems for the storage engine).
3188 We don't set TABLE_LIST::lock_type in this case as this might result
3189 in extra warnings from THD::decide_logging_format() even though
3190 binary logging is totally irrelevant for LOCK TABLES.
3191 */
3192 26 table->table->reginfo.lock_type = TL_WRITE;
3193 8538 } else if (table->lock_descriptor().type == TL_READ &&
3194
5/6
✓ Branch 0 taken 1424 times.
✓ Branch 1 taken 7114 times.
✓ Branch 2 taken 1424 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1135 times.
✓ Branch 5 taken 7403 times.
9962 !table->prelocking_placeholder &&
3195
2/2
✓ Branch 0 taken 1135 times.
✓ Branch 1 taken 289 times.
1424 table->table->file->ha_table_flags() & HA_NO_READ_LOCAL_LOCK) {
3196 /*
3197 In case when LOCK TABLE ... READ LOCAL was issued for table with
3198 storage engine which doesn't support READ LOCAL option and doesn't
3199 use THR_LOCK locks we need to upgrade weak SR metadata lock acquired
3200 in open_tables() to stronger SRO metadata lock.
3201 This is not needed for tables used through stored routines or
3202 triggers as we always acquire SRO (or even stronger SNRW) metadata
3203 lock for them.
3204 */
3205 2270 bool result = thd->mdl_context.upgrade_shared_lock(
3206
1/2
✓ Branch 0 taken 1135 times.
✗ Branch 1 not taken.
1135 table->table->mdl_ticket, MDL_SHARED_READ_ONLY,
3207 thd->variables.lock_wait_timeout);
3208
3209
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1134 times.
1135 if (deadlock_handler.need_reopen()) {
3210 /*
3211 Deadlock occurred during upgrade of metadata lock.
3212 Let us restart acquiring and opening tables for LOCK TABLES.
3213 */
3214
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 thd->pop_internal_handler();
3215
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 close_tables_for_reopen(thd, &tables, mdl_savepoint);
3216
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (open_temporary_tables(thd, tables)) goto err;
3217 1 goto retry;
3218 }
3219
3220
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1134 times.
1134 if (result) {
3221 thd->pop_internal_handler();
3222 goto err;
3223 }
3224 }
3225 }
3226 }
3227
3228
1/2
✓ Branch 0 taken 2578 times.
✗ Branch 1 not taken.
2578 thd->pop_internal_handler();
3229
3230
5/6
✓ Branch 0 taken 2578 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2564 times.
✓ Branch 3 taken 14 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 2564 times.
5142 if (lock_tables(thd, tables, counter, 0) ||
3231
2/4
✓ Branch 0 taken 2564 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2564 times.
2564 thd->locked_tables_list.init_locked_tables(thd))
3232 14 goto err;
3233
3234 2564 thd->in_lock_tables = false;
3235
3236 2564 return false;
3237
3238 55 err:
3239 55 thd->in_lock_tables = false;
3240
3241
1/2
✓ Branch 0 taken 55 times.
✗ Branch 1 not taken.
55 trans_rollback_stmt(thd);
3242 /*
3243 Need to end the current transaction, so the storage engine (InnoDB)
3244 can free its locks if LOCK TABLES locked some tables before finding
3245 that it can't lock a table in its list
3246 */
3247
1/2
✓ Branch 0 taken 55 times.
✗ Branch 1 not taken.
55 trans_rollback(thd);
3248 /* Close tables and release metadata locks. */
3249
1/2
✓ Branch 0 taken 55 times.
✗ Branch 1 not taken.
55 close_thread_tables(thd);
3250
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
55 assert(!thd->locked_tables_mode);
3251
1/2
✓ Branch 0 taken 55 times.
✗ Branch 1 not taken.
55 thd->mdl_context.release_transactional_locks();
3252 55 return true;
3253 2619 }
3254
3255 #ifdef WITH_WSREP
3256 353 static bool wsrep_is_show_query(enum enum_sql_command command) {
3257
2/4
✓ Branch 0 taken 353 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 353 times.
✗ Branch 3 not taken.
353 assert(command >= 0 && command <= SQLCOM_END);
3258 353 return (sql_command_flags[command] & CF_STATUS_COMMAND) != 0;
3259 }
3260 #endif /* WITH_WSREP */
3261
3262 /**
3263 Acquire a global backup lock.
3264
3265 @param thd Thread context.
3266
3267 @return false on success, true in case of error.
3268 */
3269
3270 254 static bool lock_tables_for_backup(THD *thd) {
3271
1/2
✓ Branch 0 taken 254 times.
✗ Branch 1 not taken.
254 DBUG_TRACE;
3272
3273
2/4
✓ Branch 0 taken 254 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 254 times.
254 if (check_backup_admin_privilege(thd)) return true;
3274
3275
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 254 times.
254 if (delay_key_write_options == DELAY_KEY_WRITE_ALL) {
3276 my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "delay_key_write=ALL");
3277 return true;
3278 }
3279 /*
3280 Do nothing if the current connection already owns the LOCK TABLES FOR
3281 BACKUP lock or the global read lock (as it's a more restrictive lock).
3282 */
3283
3/6
✓ Branch 0 taken 254 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 254 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 254 times.
508 if (thd->backup_tables_lock.is_acquired() ||
3284 254 thd->global_read_lock.is_acquired())
3285 return false;
3286
3287 /*
3288 Do not allow backup locks under regular LOCK TABLES, FLUSH TABLES ... FOR
3289 EXPORT, or FLUSH TABLES <table_list> WITH READ LOCK.
3290 */
3291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 254 times.
254 if (thd->variables.option_bits & OPTION_TABLE_LOCK) {
3292 my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
3293 return true;
3294 }
3295
3296
1/2
✓ Branch 0 taken 254 times.
✗ Branch 1 not taken.
254 bool res = thd->backup_tables_lock.acquire(thd);
3297
3298
2/4
✓ Branch 0 taken 254 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 254 times.
254 if (ha_store_binlog_info(thd)) {
3299 thd->backup_tables_lock.release(thd);
3300 res = true;
3301 }
3302
3303 254 return res;
3304 254 }
3305
3306 /**
3307 This is a wrapper for MYSQL_BIN_LOG::gtid_end_transaction. For normal
3308 statements, the function gtid_end_transaction is called in the commit
3309 handler. However, if the statement is filtered out or not written to
3310 the binary log, the commit handler is not invoked. Therefore, this
3311 wrapper calls gtid_end_transaction in case the current statement is
3312 committing but was not written to the binary log.
3313 (The function gtid_end_transaction ensures that gtid-related
3314 end-of-transaction operations are performed; this includes
3315 generating an empty transaction and calling
3316 Gtid_state::update_gtids_impl.)
3317
3318 @param thd Thread (session) context.
3319 */
3320
3321 21224920 static inline void binlog_gtid_end_transaction(THD *thd) {
3322
1/2
✓ Branch 0 taken 21226081 times.
✗ Branch 1 not taken.
21224920 DBUG_TRACE;
3323
3324 /*
3325 This performs end-of-transaction actions needed by GTIDs:
3326 in particular, it generates an empty transaction if
3327 needed (e.g., if the statement was filtered out).
3328
3329 It is executed at the end of an implicitly or explicitly
3330 committing statement.
3331
3332 In addition, it is executed after CREATE TEMPORARY TABLE
3333 or DROP TEMPORARY TABLE when they occur outside
3334 transactional context. When enforce_gtid_consistency is
3335 enabled, these statements cannot occur in transactional
3336 context, and then they behave exactly as implicitly
3337 committing: they are written to the binary log
3338 immediately, not wrapped in BEGIN/COMMIT, and cannot be
3339 rolled back. However, they do not count as implicitly
3340 committing according to stmt_causes_implicit_commit(), so
3341 we need to add special cases in the condition below. Hence
3342 the clauses for SQLCOM_CREATE_TABLE and SQLCOM_DROP_TABLE.
3343
3344 If enforce_gtid_consistency=off, CREATE TEMPORARY TABLE
3345 and DROP TEMPORARY TABLE can occur in the middle of a
3346 transaction. Then they do not behave as DDL; they are
3347 written to the binary log inside BEGIN/COMMIT.
3348
3349 (For base tables, SQLCOM_[CREATE|DROP]_TABLE match both
3350 the stmt_causes_implicit_commit(...) clause and the
3351 thd->lex->sql_command == SQLCOM_* clause; for temporary
3352 tables they match only thd->lex->sql_command == SQLCOM_*.)
3353 */
3354 63404454 if (thd->lex->sql_command == SQLCOM_COMMIT ||
3355
2/2
✓ Branch 0 taken 20951828 times.
✓ Branch 1 taken 390 times.
20952218 thd->lex->sql_command == SQLCOM_XA_PREPARE ||
3356
2/2
✓ Branch 0 taken 20951274 times.
✓ Branch 1 taken 554 times.
20951828 thd->lex->sql_command == SQLCOM_XA_COMMIT ||
3357
2/2
✓ Branch 0 taken 20951054 times.
✓ Branch 1 taken 220 times.
20951274 thd->lex->sql_command == SQLCOM_XA_ROLLBACK ||
3358
7/8
✓ Branch 0 taken 20952218 times.
✓ Branch 1 taken 273863 times.
✓ Branch 2 taken 20951178 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19752090 times.
✓ Branch 5 taken 1199088 times.
✓ Branch 6 taken 1526263 times.
✓ Branch 7 taken 19699892 times.
61930339 stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END) ||
3359
2/2
✓ Branch 0 taken 19689511 times.
✓ Branch 1 taken 62579 times.
19752090 ((thd->lex->sql_command == SQLCOM_CREATE_TABLE ||
3360
2/2
✓ Branch 0 taken 7230 times.
✓ Branch 1 taken 19682281 times.
19689511 thd->lex->sql_command == SQLCOM_DROP_TABLE) &&
3361
2/2
✓ Branch 0 taken 52149 times.
✓ Branch 1 taken 17610 times.
69809 !thd->in_multi_stmt_transaction_mode()))
3362
1/2
✓ Branch 0 taken 1526330 times.
✗ Branch 1 not taken.
1526263 (void)mysql_bin_log.gtid_end_transaction(thd);
3363 21226222 }
3364
3365 /**
3366 Execute command saved in thd and lex->sql_command.
3367
3368 @param thd Thread handle
3369 @param first_level whether invocation of the
3370 mysql_execute_command() is a top level query or sub query. At the highest
3371 level, first_level value is true. Stored procedures can execute sub queries.
3372 In such cases first_level (recursive mysql_execute_command() call) will be
3373 false.
3374
3375 @todo this is workaround. right way will be move invalidating in
3376 the unlock procedure.
3377 @todo use check_change_password()
3378
3379 @retval false OK
3380 @retval true Error
3381 */
3382
3383 21389953 int mysql_execute_command(THD *thd, bool first_level) {
3384 21389953 int res = false;
3385 21389953 LEX *const lex = thd->lex;
3386 /* first Query_block (have special meaning for many of non-SELECTcommands) */
3387 21389953 Query_block *const query_block = lex->query_block;
3388 /* first table of first Query_block */
3389 21389953 TABLE_LIST *const first_table = query_block->get_table_list();
3390 /* list of all tables in query */
3391 TABLE_LIST *all_tables;
3392 // keep GTID violation state in order to roll it back on statement failure
3393 21390468 bool gtid_consistency_violation_state = thd->has_gtid_consistency_violation;
3394
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21390677 times.
21390468 assert(query_block->master_query_expression() == lex->unit);
3395
1/2
✓ Branch 0 taken 21391437 times.
✗ Branch 1 not taken.
21390677 DBUG_TRACE;
3396 /* EXPLAIN OTHER isn't explainable command, but can have describe flag. */
3397
6/8
✓ Branch 0 taken 29254 times.
✓ Branch 1 taken 21362147 times.
✓ Branch 2 taken 29254 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 168 times.
✓ Branch 5 taken 29086 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 168 times.
21391437 assert(!lex->is_explain() || is_explainable_query(lex->sql_command) ||
3398 lex->sql_command == SQLCOM_EXPLAIN_OTHER);
3399
3400
3/4
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 21391314 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 27 times.
21391401 assert(!thd->m_transactional_ddl.inited() ||
3401 thd->in_active_multi_stmt_transaction());
3402
3403 21391341 bool early_error_on_rep_command{false};
3404
3405
2/4
✓ Branch 0 taken 21391151 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21391414 times.
✗ Branch 3 not taken.
21391341 CONDITIONAL_SYNC_POINT_FOR_TIMESTAMP("before_execute_command");
3406
3407 /*
3408 If there is a CREATE TABLE...START TRANSACTION command which
3409 is not yet committed or rollbacked, then we should allow only
3410 BINLOG INSERT, COMMIT or ROLLBACK command.
3411 TODO: Should we really check name of table when we cable BINLOG INSERT ?
3412 */
3413
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 13 times.
21391675 if (thd->m_transactional_ddl.inited() && lex->sql_command != SQLCOM_COMMIT &&
3414
6/6
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 21391349 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 21391372 times.
21391414 lex->sql_command != SQLCOM_ROLLBACK &&
3415
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7 times.
11 lex->sql_command != SQLCOM_BINLOG_BASE64_EVENT) {
3416
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 my_error(ER_STATEMENT_NOT_ALLOWED_AFTER_START_TRANSACTION, MYF(0));
3417
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 binlog_gtid_end_transaction(thd);
3418 4 return 1;
3419 }
3420
3421 21391372 thd->work_part_info = nullptr;
3422
3423
2/2
✓ Branch 0 taken 2026 times.
✓ Branch 1 taken 21388924 times.
21391372 if (thd->optimizer_switch_flag(OPTIMIZER_SWITCH_SUBQUERY_TO_DERIVED))
3424 2026 lex->add_statement_options(OPTION_NO_CONST_TABLES);
3425
3426 /*
3427 Each statement or replication event which might produce deadlock
3428 should handle transaction rollback on its own. So by the start of
3429 the next statement transaction rollback request should be fulfilled
3430 already.
3431 */
3432
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 21390950 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
21390950 assert(!thd->transaction_rollback_request || thd->in_sub_stmt);
3433 /*
3434 In many cases first table of main Query_block have special meaning =>
3435 check that it is first table in global list and relink it first in
3436 queries_tables list if it is necessary (we need such relinking only
3437 for queries with subqueries in select list, in this case tables of
3438 subqueries will go to global list first)
3439
3440 all_tables will differ from first_table only if most upper Query_block
3441 do not contain tables.
3442
3443 Because of above in place where should be at least one table in most
3444 outer Query_block we have following check:
3445 assert(first_table == all_tables);
3446 assert(first_table == all_tables && first_table != 0);
3447 */
3448
1/2
✓ Branch 0 taken 21391189 times.
✗ Branch 1 not taken.
21390950 lex->first_lists_tables_same();
3449 /* should be assigned after making first tables same */
3450 21391189 all_tables = lex->query_tables;
3451 /* set context for commands which do not use setup_tables */
3452 21391189 query_block->context.resolve_in_table_list_only(
3453 query_block->get_table_list());
3454
3455
1/2
✓ Branch 0 taken 21391548 times.
✗ Branch 1 not taken.
21389700 thd->get_stmt_da()->reset_diagnostics_area();
3456
2/2
✓ Branch 0 taken 20738245 times.
✓ Branch 1 taken 653303 times.
21391548 if ((thd->lex->keep_diagnostics != DA_KEEP_PARSE_ERROR) &&
3457
2/2
✓ Branch 0 taken 20626008 times.
✓ Branch 1 taken 112237 times.
20738245 (thd->lex->keep_diagnostics != DA_KEEP_DIAGNOSTICS)) {
3458 /*
3459 No parse errors, and it's not a diagnostic statement:
3460 remove the sql conditions from the DA!
3461 For diagnostic statements we need to keep the conditions
3462 around so we can inspec them.
3463 */
3464
1/2
✓ Branch 0 taken 20625777 times.
✗ Branch 1 not taken.
20626008 thd->get_stmt_da()->reset_condition_info(thd);
3465 }
3466
3467
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 21391133 times.
21391317 if (thd->resource_group_ctx()->m_warn != 0) {
3468 4 auto res_grp_name = thd->resource_group_ctx()->m_switch_resource_group_str;
3469
2/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4 switch (thd->resource_group_ctx()->m_warn) {
3470 case WARN_RESOURCE_GROUP_UNSUPPORTED: {
3471 auto res_grp_mgr = resourcegroups::Resource_group_mgr::instance();
3472 push_warning_printf(thd, Sql_condition::SL_WARNING,
3473 ER_FEATURE_UNSUPPORTED,
3474 ER_THD(thd, ER_FEATURE_UNSUPPORTED),
3475 "Resource groups", res_grp_mgr->unsupport_reason());
3476 break;
3477 }
3478 case WARN_RESOURCE_GROUP_UNSUPPORTED_HINT:
3479 push_warning_printf(thd, Sql_condition::SL_WARNING,
3480 ER_WARN_UNSUPPORTED_HINT,
3481 ER_THD(thd, ER_WARN_UNSUPPORTED_HINT),
3482 "Subquery or Stored procedure or Trigger");
3483 break;
3484 3 case WARN_RESOURCE_GROUP_TYPE_MISMATCH: {
3485 3 ulonglong pfs_thread_id = 0;
3486 /*
3487 Resource group is unsupported with DISABLE_PSI_THREAD.
3488 The below #ifdef is required for compilation when DISABLE_PSI_THREAD
3489 is enabled.
3490 */
3491 #ifdef HAVE_PSI_THREAD_INTERFACE
3492
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 pfs_thread_id = PSI_THREAD_CALL(get_current_thread_internal_id)();
3493 #endif // HAVE_PSI_THREAD_INTERFACE
3494
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 push_warning_printf(thd, Sql_condition::SL_WARNING,
3495 ER_RESOURCE_GROUP_BIND_FAILED,
3496 ER_THD(thd, ER_RESOURCE_GROUP_BIND_FAILED),
3497 res_grp_name, pfs_thread_id,
3498 "System resource group can't be bound"
3499 " with a session thread");
3500 3 break;
3501 }
3502 1 case WARN_RESOURCE_GROUP_NOT_EXISTS:
3503
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 push_warning_printf(
3504 thd, Sql_condition::SL_WARNING, ER_RESOURCE_GROUP_NOT_EXISTS,
3505 ER_THD(thd, ER_RESOURCE_GROUP_NOT_EXISTS), res_grp_name);
3506 1 break;
3507 case WARN_RESOURCE_GROUP_ACCESS_DENIED:
3508 push_warning_printf(thd, Sql_condition::SL_WARNING,
3509 ER_SPECIFIC_ACCESS_DENIED_ERROR,
3510 ER_THD(thd, ER_SPECIFIC_ACCESS_DENIED_ERROR),
3511 "SUPER OR RESOURCE_GROUP_ADMIN OR "
3512 "RESOURCE_GROUP_USER");
3513 }
3514 4 thd->resource_group_ctx()->m_warn = 0;
3515 4 res_grp_name[0] = '\0';
3516 }
3517
3518
2/2
✓ Branch 0 taken 536265 times.
✓ Branch 1 taken 20853916 times.
21391137 if (unlikely(thd->slave_thread)) {
3519
3/4
✓ Branch 0 taken 536523 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 286 times.
✓ Branch 3 taken 536237 times.
536265 if (!check_database_filters(thd, thd->db().str, lex->sql_command)) {
3520
1/2
✓ Branch 0 taken 286 times.
✗ Branch 1 not taken.
286 binlog_gtid_end_transaction(thd);
3521 286 return 0;
3522 }
3523
3524
2/2
✓ Branch 0 taken 903 times.
✓ Branch 1 taken 535334 times.
536237 if (lex->sql_command == SQLCOM_DROP_TRIGGER) {
3525 /*
3526 When dropping a trigger, we need to load its table name
3527 before checking slave filter rules.
3528 */
3529 903 TABLE_LIST *trigger_table = nullptr;
3530
1/2
✓ Branch 0 taken 903 times.
✗ Branch 1 not taken.
903 (void)get_table_for_trigger(thd, lex->spname->m_db, lex->spname->m_name,
3531 true, &trigger_table);
3532
2/2
✓ Branch 0 taken 869 times.
✓ Branch 1 taken 34 times.
903 if (trigger_table != nullptr) {
3533 869 lex->add_to_query_tables(trigger_table);
3534 869 all_tables = trigger_table;
3535 } else {
3536 /*
3537 If table name cannot be loaded,
3538 it means the trigger does not exists possibly because
3539 CREATE TRIGGER was previously skipped for this trigger
3540 according to slave filtering rules.
3541 Returning success without producing any errors in this case.
3542 */
3543
1/2
✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
34 binlog_gtid_end_transaction(thd);
3544 34 return 0;
3545 }
3546
3547 // force searching in slave.cc:tables_ok()
3548 869 all_tables->updating = true;
3549 }
3550
3551 /*
3552 For fix of BUG#37051, the master stores the table map for update
3553 in the Query_log_event, and the value is assigned to
3554 thd->table_map_for_update before executing the update
3555 query.
3556
3557 If thd->table_map_for_update is set, then we are
3558 replicating from a new master, we can use this value to apply
3559 filter rules without opening all the tables. However If
3560 thd->table_map_for_update is not set, then we are
3561 replicating from an old master, so we just skip this and
3562 continue with the old method. And of course, the bug would still
3563 exist for old masters.
3564 */
3565
4/4
✓ Branch 0 taken 481 times.
✓ Branch 1 taken 535722 times.
✓ Branch 2 taken 479 times.
✓ Branch 3 taken 2 times.
536203 if (lex->sql_command == SQLCOM_UPDATE_MULTI && thd->table_map_for_update) {
3566 479 table_map table_map_for_update = thd->table_map_for_update;
3567 479 uint nr = 0;
3568 TABLE_LIST *table;
3569
2/2
✓ Branch 0 taken 5081 times.
✓ Branch 1 taken 479 times.
5560 for (table = all_tables; table; table = table->next_global, nr++) {
3570
2/2
✓ Branch 0 taken 2657 times.
✓ Branch 1 taken 2424 times.
5081 if (table_map_for_update & ((table_map)1 << nr))
3571 2657 table->updating = true;
3572 else
3573 2424 table->updating = false;
3574 }
3575
3576
3/4
✓ Branch 0 taken 479 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 441 times.
479 if (all_tables_not_ok(thd, all_tables)) {
3577 /* we warn the slave SQL thread */
3578
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
3579
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 binlog_gtid_end_transaction(thd);
3580 38 return 0;
3581 }
3582
3583
2/2
✓ Branch 0 taken 4957 times.
✓ Branch 1 taken 441 times.
5398 for (table = all_tables; table; table = table->next_global)
3584 4957 table->updating = true;
3585 }
3586
3587 /*
3588 Check if statement should be skipped because of slave filtering
3589 rules
3590
3591 Exceptions are:
3592 - UPDATE MULTI: For this statement, we want to check the filtering
3593 rules later in the code
3594 - SET: we always execute it (Not that many SET commands exists in
3595 the binary log anyway -- only 4.1 masters write SET statements,
3596 in 5.0 there are no SET statements in the binary log)
3597 - DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
3598 have stale files on slave caused by exclusion of one tmp table).
3599 */
3600 1607164 if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
3601
2/2
✓ Branch 0 taken 533792 times.
✓ Branch 1 taken 1501 times.
535293 !(lex->sql_command == SQLCOM_SET_OPTION) &&
3602
4/4
✓ Branch 0 taken 10610 times.
✓ Branch 1 taken 523182 times.
✓ Branch 2 taken 862 times.
✓ Branch 3 taken 9748 times.
533792 !(lex->sql_command == SQLCOM_DROP_TABLE && lex->drop_temporary &&
3603
6/6
✓ Branch 0 taken 535293 times.
✓ Branch 1 taken 872 times.
✓ Branch 2 taken 597 times.
✓ Branch 3 taken 265 times.
✓ Branch 4 taken 281 times.
✓ Branch 5 taken 535425 times.
1071596 lex->drop_if_exists) &&
3604
3/4
✓ Branch 0 taken 533068 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 281 times.
✓ Branch 3 taken 532787 times.
533527 all_tables_not_ok(thd, all_tables)) {
3605 /* we warn the slave SQL thread */
3606
1/2
✓ Branch 0 taken 281 times.
✗ Branch 1 not taken.
281 my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
3607
1/2
✓ Branch 0 taken 281 times.
✗ Branch 1 not taken.
281 binlog_gtid_end_transaction(thd);
3608 281 return 0;
3609 }
3610 /*
3611 Execute deferred events first
3612 */
3613
2/4
✓ Branch 0 taken 536120 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 536120 times.
535425 if (slave_execute_deferred_events(thd)) return -1;
3614
3615
1/2
✓ Branch 0 taken 535943 times.
✗ Branch 1 not taken.
536120 int ret = launch_hook_trans_begin(thd, all_tables);
3616
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 535943 times.
535943 if (ret) {
3617 my_error(ret, MYF(0));
3618 return -1;
3619 }
3620
3621 } else {
3622
1/2
✓ Branch 0 taken 20854482 times.
✗ Branch 1 not taken.
20853916 int ret = launch_hook_trans_begin(thd, all_tables);
3623
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 20854466 times.
20854482 if (ret) {
3624
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 my_error(ret, MYF(0));
3625 16 return -1;
3626 }
3627
3628 /*
3629 When option readonly is set deny operations which change non-temporary
3630 tables. Except for the replication thread and the 'super' users.
3631 */
3632
3/4
✓ Branch 0 taken 20854261 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 73 times.
✓ Branch 3 taken 20854188 times.
20854466 if (deny_updates_if_read_only_option(thd, all_tables)) {
3633 73 thd->diff_access_denied_errors++;
3634
1/2
✓ Branch 0 taken 73 times.
✗ Branch 1 not taken.
73 err_readonly(thd);
3635 73 return -1;
3636 }
3637 } /* endif unlikely slave */
3638
3639 21390131 thd->status_var.com_stat[lex->sql_command]++;
3640
3641 Opt_trace_start ots(thd, all_tables, lex->sql_command, &lex->var_list,
3642
1/2
✓ Branch 0 taken 21390762 times.
✗ Branch 1 not taken.
21390718 thd->query().str, thd->query().length, nullptr,
3643
2/4
✓ Branch 0 taken 21390718 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21390874 times.
✗ Branch 3 not taken.
64170034 thd->variables.character_set_client);
3644
3645
1/2
✓ Branch 0 taken 21390059 times.
✗ Branch 1 not taken.
42779699 Opt_trace_object trace_command(&thd->opt_trace);
3646
1/2
✓ Branch 0 taken 21390444 times.
✗ Branch 1 not taken.
42778920 Opt_trace_array trace_command_steps(&thd->opt_trace, "steps");
3647
3648 #ifdef WITH_WSREP
3649
8/8
✓ Branch 0 taken 21390250 times.
✓ Branch 1 taken 194 times.
✓ Branch 2 taken 2904866 times.
✓ Branch 3 taken 18485384 times.
✓ Branch 4 taken 329145 times.
✓ Branch 5 taken 2575721 times.
✓ Branch 6 taken 279392 times.
✓ Branch 7 taken 49753 times.
21390444 if (WSREP(thd)) {
3650 /*
3651 * bail out if DB snapshot has not been installed. We however,
3652 * allow SET and SHOW queries and reads from information schema
3653 * and dirty reads (if configured)
3654 */
3655 804956 if (!thd->wsrep_applier &&
3656
5/6
✓ Branch 0 taken 246090 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 244487 times.
✓ Branch 3 taken 1603 times.
✓ Branch 4 taken 7 times.
✓ Branch 5 taken 244480 times.
246052 !(wsrep_ready_get() && wsrep_reject_queries == WSREP_REJECT_NONE) &&
3657
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 1552 times.
1610 !(thd->variables.wsrep_dirty_reads &&
3658
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 53 times.
58 (sql_command_flags[lex->sql_command] & CF_CHANGES_DATA) == 0) &&
3659
3/4
✓ Branch 0 taken 1557 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 580 times.
✓ Branch 3 taken 977 times.
1557 !wsrep_tables_accessible_when_detached(all_tables) &&
3660
2/2
✓ Branch 0 taken 364 times.
✓ Branch 1 taken 216 times.
580 lex->sql_command != SQLCOM_SET_OPTION &&
3661
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 4 times.
364 lex->sql_command != SQLCOM_SHUTDOWN &&
3662
7/8
✓ Branch 0 taken 246052 times.
✓ Branch 1 taken 33340 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 346 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 17 times.
✓ Branch 7 taken 279457 times.
525835 !(lex->sql_command == SQLCOM_SELECT && !all_tables) &&
3663
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 336 times.
309 !wsrep_is_show_query(lex->sql_command)) {
3664
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 my_message(ER_UNKNOWN_COM_ERROR,
3665 "WSREP has not yet prepared node for application use", MYF(0));
3666 17 return -1;
3667 }
3668
3/4
✓ Branch 0 taken 279524 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 279521 times.
279457 if (block_write_while_in_rolling_upgrade(thd)) {
3669 3 return -1;
3670 }
3671 }
3672 #endif /* WITH_WSREP */
3673
3674
6/6
✓ Branch 0 taken 18433606 times.
✓ Branch 1 taken 2956967 times.
✓ Branch 2 taken 114693 times.
✓ Branch 3 taken 18318780 times.
✓ Branch 4 taken 114721 times.
✓ Branch 5 taken 21275719 times.
21390573 if (lex->m_sql_cmd && lex->m_sql_cmd->owner())
3675
1/2
✓ Branch 0 taken 114468 times.
✗ Branch 1 not taken.
114721 lex->m_sql_cmd->owner()->trace_parameter_types();
3676
3677
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21389755 times.
21390187 assert(thd->get_transaction()->cannot_safely_rollback(
3678 Transaction_ctx::STMT) == false);
3679
3680
4/6
✓ Branch 0 taken 21390487 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21365868 times.
✓ Branch 3 taken 132 times.
✓ Branch 4 taken 24684 times.
✗ Branch 5 not taken.
21389755 switch (gtid_pre_statement_checks(thd)) {
3681 21365868 case GTID_STATEMENT_EXECUTE:
3682 21365868 break;
3683 132 case GTID_STATEMENT_CANCEL:
3684 132 return -1;
3685 24684 case GTID_STATEMENT_SKIP:
3686
1/2
✓ Branch 0 taken 24684 times.
✗ Branch 1 not taken.
24684 my_ok(thd);
3687
1/2
✓ Branch 0 taken 24684 times.
✗ Branch 1 not taken.
24684 binlog_gtid_end_transaction(thd);
3688 24684 return 0;
3689 }
3690
3691
2/2
✓ Branch 0 taken 36056 times.
✓ Branch 1 taken 21329615 times.
21365671 if (thd->variables.require_row_format) {
3692
3/4
✓ Branch 0 taken 36039 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 36028 times.
36056 if (evaluate_command_row_only_restrictions(thd)) {
3693
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 my_error(ER_CLIENT_QUERY_FAILURE_INVALID_NON_ROW_FORMAT, MYF(0));
3694 11 return -1;
3695 }
3696 }
3697
3698 /*
3699 End a active transaction so that this command will have it's
3700 own transaction and will also sync the binary log. If a DDL is
3701 not run in it's own transaction it may simply never appear on
3702 the slave in case the outside transaction rolls back.
3703 */
3704
3/4
✓ Branch 0 taken 21366015 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1266051 times.
✓ Branch 3 taken 20099964 times.
21365643 if (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_BEGIN)) {
3705 /*
3706 Note that this should never happen inside of stored functions
3707 or triggers as all such statements prohibited there.
3708 */
3709
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1266051 times.
1266051 assert(!thd->in_sub_stmt);
3710 /* Statement transaction still should not be started. */
3711
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1266047 times.
1266051 assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT));
3712
3713 /*
3714 Implicit commit is not allowed with an active XA transaction.
3715 In this case we should not release metadata locks as the XA transaction
3716 will not be rolled back. Therefore we simply return here.
3717 */
3718
3/4
✓ Branch 0 taken 1266057 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1266055 times.
1266047 if (trans_check_state(thd)) return -1;
3719
3720 /* Commit the normal transaction if one is active. */
3721 #ifdef WITH_WSREP
3722
2/4
✓ Branch 0 taken 1266054 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1266054 times.
1266055 if (trans_commit_implicit(thd)) {
3723 thd->mdl_context.release_transactional_locks();
3724 WSREP_DEBUG(
3725 "Transaction implicit commit failed"
3726 " MDL released: %u",
3727 thd->thread_id());
3728 return -1;
3729 }
3730 #else
3731 if (trans_commit_implicit(thd)) return -1;
3732 #endif /* WITH_WSREP */
3733
3734 /* Release metadata locks acquired in this transaction. */
3735
1/2
✓ Branch 0 taken 1266051 times.
✗ Branch 1 not taken.
1266054 thd->mdl_context.release_transactional_locks();
3736
3737 #ifdef WITH_WSREP
3738 /*
3739 Clean up the previous transaction on implicit commit.
3740 If it was not empty transaction, it already has been commited
3741 to Galera in trans_commit_implicit().
3742 If it was empty transaction (no work sets), trans_commit_implicit()
3743 did nothing to Galera, so we need to commit empty transaction.
3744 */
3745
3/4
✓ Branch 0 taken 1266039 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1258523 times.
✓ Branch 3 taken 7516 times.
1266051 if (wsrep_thd_is_local(thd)) {
3746
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1258520 times.
1258523 if (wsrep_has_changes(thd)) {
3747
2/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
9 if (wsrep_after_statement(thd)) {
3748 return -1;
3749 }
3750 } else {
3751
1/2
✓ Branch 0 taken 1258462 times.
✗ Branch 1 not taken.
1258520 wsrep_commit_empty(thd, true);
3752 }
3753 }
3754 #endif /* WITH_WSREP */
3755 }
3756
3757
3/4
✓ Branch 0 taken 19284981 times.
✓ Branch 1 taken 2079956 times.
✓ Branch 2 taken 19286013 times.
✗ Branch 3 not taken.
21365951 DEBUG_SYNC(thd, "after_implicit_pre_commit");
3758
3759
3/4
✓ Branch 0 taken 21366061 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 519 times.
✓ Branch 3 taken 21365542 times.
21365969 if (gtid_pre_statement_post_implicit_commit_checks(thd)) return -1;
3760
3761
7/8
✓ Branch 0 taken 13650129 times.
✓ Branch 1 taken 7715413 times.
✓ Branch 2 taken 13650119 times.
✓ Branch 3 taken 7715423 times.
✓ Branch 4 taken 21365075 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 7 times.
✓ Branch 7 taken 21365068 times.
21365542 if (mysql_audit_notify(thd,
3762 first_level ? MYSQL_AUDIT_QUERY_START
3763 : MYSQL_AUDIT_QUERY_NESTED_START,
3764 first_level ? "MYSQL_AUDIT_QUERY_START"
3765 : "MYSQL_AUDIT_QUERY_NESTED_START")) {
3766 7 return 1;
3767 }
3768
3769 #ifndef NDEBUG
3770
2/2
✓ Branch 0 taken 19860531 times.
✓ Branch 1 taken 1504537 times.
21365068 if (lex->sql_command != SQLCOM_SET_OPTION)
3771
3/4
✓ Branch 0 taken 17828230 times.
✓ Branch 1 taken 2031859 times.
✓ Branch 2 taken 17828818 times.
✗ Branch 3 not taken.
19860531 DEBUG_SYNC(thd, "before_execute_sql_command");
3772 #endif
3773
3774 /*
3775 Start a new transaction if CREATE TABLE has START TRANSACTION clause.
3776 Disable binlog so that the BEGIN is not logged in binlog.
3777 */
3778
4/4
✓ Branch 0 taken 878933 times.
✓ Branch 1 taken 20486281 times.
✓ Branch 2 taken 70 times.
✓ Branch 3 taken 878863 times.
21365214 if (lex->create_info && lex->create_info->m_transactional_ddl &&
3779
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 47 times.
70 !thd->slave_thread) {
3780 23 Disable_binlog_guard binlog_guard(thd);
3781
2/4
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 23 times.
23 if (trans_begin(thd, MYSQL_START_TRANS_OPT_READ_WRITE)) return true;
3782
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 }
3783
3784 /*
3785 For statements which need this, prevent InnoDB from automatically
3786 committing InnoDB transaction each time data-dictionary tables are
3787 closed after being updated.
3788 */
3789 Disable_autocommit_guard autocommit_guard(
3790
2/2
✓ Branch 0 taken 1125898 times.
✓ Branch 1 taken 14996 times.
22505967 sqlcom_needs_autocommit_off(lex) && !thd->is_plugin_fake_ddl() ? thd
3791
2/2
✓ Branch 0 taken 1140753 times.
✓ Branch 1 taken 20223794 times.
43869493 : nullptr);
3792
3793 /*
3794 Check if we are in a read-only transaction and we're trying to
3795 execute a statement which should always be disallowed in such cases.
3796
3797 Note that this check is done after any implicit commits.
3798 */
3799
2/2
✓ Branch 0 taken 249 times.
✓ Branch 1 taken 21363820 times.
21364069 if (thd->tx_read_only &&
3800
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 228 times.
249 (sql_command_flags[lex->sql_command] & CF_DISALLOW_IN_RO_TRANS)) {
3801 21 thd->diff_access_denied_errors++;
3802
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 my_error(ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION, MYF(0));
3803 21 goto error;
3804 }
3805
3806 /*
3807 Close tables open by HANDLERs before executing DDL statement
3808 which is going to affect those tables.
3809
3810 This should happen before temporary tables are pre-opened as
3811 otherwise we will get errors about attempt to re-open tables
3812 if table to be changed is open through HANDLER.
3813
3814 Note that even although this is done before any privilege
3815 checks there is no security problem here as closing open
3816 HANDLER doesn't require any privileges anyway.
3817 */
3818
2/2
✓ Branch 0 taken 955801 times.
✓ Branch 1 taken 20408247 times.
21364048 if (sql_command_flags[lex->sql_command] & CF_HA_CLOSE)
3819
1/2
✓ Branch 0 taken 955801 times.
✗ Branch 1 not taken.
955801 mysql_ha_rm_tables(thd, all_tables);
3820
3821 /*
3822 Check that the command is allowed on the PROTOCOL_PLUGIN
3823 */
3824
5/6
✓ Branch 0 taken 21363794 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 105357 times.
✓ Branch 3 taken 21258437 times.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 21363779 times.
21469405 if (thd->get_protocol()->type() == Protocol::PROTOCOL_PLUGIN &&
3825
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 105342 times.
105357 !(sql_command_flags[lex->sql_command] & CF_ALLOW_PROTOCOL_PLUGIN)) {
3826
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 my_error(ER_PLUGGABLE_PROTOCOL_COMMAND_NOT_SUPPORTED, MYF(0));
3827 15 goto error;
3828 }
3829
3830 /*
3831 Pre-open temporary tables to simplify privilege checking
3832 for statements which need this.
3833 */
3834
2/2
✓ Branch 0 taken 19347065 times.
✓ Branch 1 taken 2016714 times.
21363779 if (sql_command_flags[lex->sql_command] & CF_PREOPEN_TMP_TABLES) {
3835
3/4
✓ Branch 0 taken 19347301 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 19347276 times.
19347065 if (open_temporary_tables(thd, all_tables)) goto error;
3836 }
3837
3838 // Save original info for EXPLAIN FOR CONNECTION
3839
2/2
✓ Branch 0 taken 21239945 times.
✓ Branch 1 taken 124045 times.
21363990 if (!thd->in_sub_stmt)
3840 42479988 thd->query_plan.set_query_plan(lex->sql_command, lex,
3841
1/2
✓ Branch 0 taken 21241516 times.
✗ Branch 1 not taken.
21239945 !thd->stmt_arena->is_regular());
3842
3843 /* Update system variables specified in SET_VAR hints. */
3844
4/4
✓ Branch 0 taken 7751 times.
✓ Branch 1 taken 21357810 times.
✓ Branch 2 taken 6736 times.
✓ Branch 3 taken 1015 times.
21365561 if (lex->opt_hints_global && lex->opt_hints_global->sys_var_hint)
3845
1/2
✓ Branch 0 taken 6736 times.
✗ Branch 1 not taken.
6736 lex->opt_hints_global->sys_var_hint->update_vars(thd);
3846
3847 /* Check if the statement fulfill the requirements on ACL CACHE */
3848
3/4
✓ Branch 0 taken 21364532 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 21364530 times.
21365561 if (!command_satisfy_acl_cache_requirement(lex->sql_command)) {
3849
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables");
3850 2 goto error;
3851 }
3852
3853
9/10
✓ Branch 0 taken 21364393 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 76 times.
✓ Branch 3 taken 21364317 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 74 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 75 times.
21364530 DBUG_EXECUTE_IF(
3854 "force_rollback_in_replica_on_transactional_ddl_commit",
3855 if (thd->m_transactional_ddl.inited() &&
3856 thd->lex->sql_command == SQLCOM_COMMIT) {
3857 lex->sql_command = SQLCOM_ROLLBACK;
3858 });
3859 #ifdef WITH_WSREP
3860 /*
3861 Always start a new transaction for a wsrep THD unless the
3862 current command is DDL or explicit BEGIN. This will guarantee that
3863 the THD is BF abortable even if it does not generate any
3864 changes and takes only read locks. If the statement does not
3865 start a multi STMT transaction, the wsrep_transaction is
3866 committed as empty at the end of this function.
3867
3868 Transaction is started for BEGIN in trans_begin(), for DDL the
3869 implicit commit took care of committing previous transaction
3870 above and a new transaction should not be started.
3871
3872 Do not start transaction for stored procedures, it will be handled
3873 internally in SP processing.
3874 */
3875
9/10
✓ Branch 0 taken 2904839 times.
✓ Branch 1 taken 18459298 times.
✓ Branch 2 taken 329123 times.
✓ Branch 3 taken 2575716 times.
✓ Branch 4 taken 279406 times.
✓ Branch 5 taken 49717 times.
✓ Branch 6 taken 279380 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 245971 times.
✓ Branch 9 taken 33409 times.
21364137 if (WSREP(thd) && wsrep_thd_is_local(thd) &&
3876
4/4
✓ Branch 0 taken 245352 times.
✓ Branch 1 taken 619 times.
✓ Branch 2 taken 236209 times.
✓ Branch 3 taken 9143 times.
245971 lex->sql_command != SQLCOM_BEGIN && lex->sql_command != SQLCOM_CALL &&
3877
6/6
✓ Branch 0 taken 21364137 times.
✓ Branch 1 taken 256 times.
✓ Branch 2 taken 236130 times.
✓ Branch 3 taken 79 times.
✓ Branch 4 taken 184265 times.
✓ Branch 5 taken 21180102 times.
42964634 lex->sql_command != SQLCOM_EXECUTE &&
3878
2/2
✓ Branch 0 taken 184258 times.
✓ Branch 1 taken 51872 times.
236130 !(sql_command_flags[lex->sql_command] & CF_AUTO_COMMIT_TRANS)) {
3879
1/2
✓ Branch 0 taken 184253 times.
✗ Branch 1 not taken.
184265 wsrep_start_trx_if_not_started(thd);
3880 }
3881 #endif /* WITH_WSREP */
3882
3883 /*
3884 We do not flag "is DML" (TX_STMT_DML) here as replication expects us to
3885 test for LOCK TABLE etc. first. To rephrase, we try not to set TX_STMT_DML
3886 until we have the MDL, and LOCK TABLE could massively delay this.
3887 */
3888
3889
58/59
✓ Branch 0 taken 48128 times.
✓ Branch 1 taken 115461 times.
✓ Branch 2 taken 42775 times.
✓ Branch 3 taken 14343 times.
✓ Branch 4 taken 21 times.
✓ Branch 5 taken 111 times.
✓ Branch 6 taken 26 times.
✓ Branch 7 taken 7865 times.
✓ Branch 8 taken 2227 times.
✓ Branch 9 taken 2053 times.
✓ Branch 10 taken 7030 times.
✓ Branch 11 taken 5884 times.
✓ Branch 12 taken 10000 times.
✓ Branch 13 taken 25623 times.
✓ Branch 14 taken 7894225 times.
✓ Branch 15 taken 352708 times.
✓ Branch 16 taken 678214 times.
✓ Branch 17 taken 160725 times.
✓ Branch 18 taken 89892 times.
✓ Branch 19 taken 1504619 times.
✓ Branch 20 taken 922 times.
✓ Branch 21 taken 4453 times.
✓ Branch 22 taken 2867 times.
✓ Branch 23 taken 35 times.
✓ Branch 24 taken 254 times.
✓ Branch 25 taken 79 times.
✓ Branch 26 taken 90 times.
✓ Branch 27 taken 15607 times.
✓ Branch 28 taken 6136 times.
✓ Branch 29 taken 975 times.
✓ Branch 30 taken 1142 times.
✓ Branch 31 taken 500 times.
✓ Branch 32 taken 205 times.
✓ Branch 33 taken 6788 times.
✓ Branch 34 taken 5621 times.
✓ Branch 35 taken 523 times.
✓ Branch 36 taken 1698 times.
✓ Branch 37 taken 12918 times.
✓ Branch 38 taken 26040 times.
✓ Branch 39 taken 23156 times.
✓ Branch 40 taken 2564 times.
✓ Branch 41 taken 1141 times.
✓ Branch 42 taken 355100 times.
✓ Branch 43 taken 273657 times.
✓ Branch 44 taken 10716 times.
✓ Branch 45 taken 38 times.
✓ Branch 46 taken 4286 times.
✓ Branch 47 taken 8288 times.
✓ Branch 48 taken 36017 times.
✓ Branch 49 taken 388 times.
✓ Branch 50 taken 37874 times.
✓ Branch 51 taken 67480 times.
✓ Branch 52 taken 4822 times.
✓ Branch 53 taken 23839 times.
✓ Branch 54 taken 3702 times.
✓ Branch 55 taken 158956 times.
✓ Branch 56 taken 9301005 times.
✓ Branch 57 taken 2543 times.
✗ Branch 58 not taken.
21364355 switch (lex->sql_command) {
3890 48128 case SQLCOM_PREPARE: {
3891
1/2
✓ Branch 0 taken 48126 times.
✗ Branch 1 not taken.
48128 mysql_sql_stmt_prepare(thd);
3892 48126 break;
3893 }
3894 115461 case SQLCOM_EXECUTE: {
3895
1/2
✓ Branch 0 taken 115716 times.
✗ Branch 1 not taken.
115461 mysql_sql_stmt_execute(thd);
3896 115716 break;
3897 }
3898 42775 case SQLCOM_DEALLOCATE_PREPARE: {
3899
1/2
✓ Branch 0 taken 42780 times.
✗ Branch 1 not taken.
42775 mysql_sql_stmt_close(thd);
3900 42780 break;
3901 }
3902
3903 14343 case SQLCOM_EMPTY_QUERY:
3904
1/2
✓ Branch 0 taken 14343 times.
✗ Branch 1 not taken.
14343 my_ok(thd);
3905 14343 break;
3906
3907 21 case SQLCOM_HELP:
3908
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 res = mysqld_help(thd, lex->help_arg);
3909 21 break;
3910
3911 111 case SQLCOM_PURGE: {
3912 111 Security_context *sctx = thd->security_context();
3913
6/16
✓ Branch 0 taken 111 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 111 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 111 times.
✓ Branch 6 taken 111 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 111 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 111 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
111 if (!sctx->check_access(SUPER_ACL) &&
3914 !sctx->has_global_grant(STRING_WITH_LEN("BINLOG_ADMIN")).first) {
3915 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0),
3916 "SUPER or BINLOG_ADMIN");
3917 goto error;
3918 }
3919 /* PURGE MASTER LOGS TO 'file' */
3920
1/2
✓ Branch 0 taken 111 times.
✗ Branch 1 not taken.
111 res = purge_source_logs_to_file(thd, lex->to_log);
3921 111 break;
3922 }
3923 26 case SQLCOM_PURGE_BEFORE: {
3924 Item *it;
3925 26 Security_context *sctx = thd->security_context();
3926
6/16
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 26 times.
✓ Branch 6 taken 26 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 26 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 26 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
26 if (!sctx->check_access(SUPER_ACL) &&
3927 !sctx->has_global_grant(STRING_WITH_LEN("BINLOG_ADMIN")).first) {
3928 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0),
3929 "SUPER or BINLOG_ADMIN");
3930 goto error;
3931 }
3932 /* PURGE MASTER LOGS BEFORE 'data' */
3933 26 it = lex->purge_value_list.head();
3934
7/12
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 26 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 26 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 26 times.
26 if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1)) {
3935 my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
3936 goto error;
3937 }
3938
2/4
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
26 it = new Item_func_unix_timestamp(it);
3939 /*
3940 it is OK only emulate fix_fieds, because we need only
3941 value of constant
3942 */
3943 26 it->quick_fix_field();
3944
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 time_t purge_time = static_cast<time_t>(it->val_int());
3945
2/4
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 26 times.
26 if (thd->is_error()) goto error;
3946
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 res = purge_source_logs_before_date(thd, purge_time);
3947 26 break;
3948 }
3949 7865 case SQLCOM_CHANGE_MASTER: {
3950 7865 Security_context *sctx = thd->security_context();
3951
6/16
✓ Branch 0 taken 7865 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7865 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 7865 times.
✓ Branch 6 taken 7865 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7865 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 7865 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
7865 if (!sctx->check_access(SUPER_ACL) &&
3952 !sctx->has_global_grant(STRING_WITH_LEN("REPLICATION_SLAVE_ADMIN"))
3953 .first) {
3954 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0),
3955 "SUPER or REPLICATION_SLAVE_ADMIN");
3956 goto error;
3957 }
3958
1/2
✓ Branch 0 taken 7865 times.
✗ Branch 1 not taken.
7865 res = change_master_cmd(thd);
3959 7865 break;
3960 }
3961 2227 case SQLCOM_START_GROUP_REPLICATION: {
3962 2227 Security_context *sctx = thd->security_context();
3963
8/16
✓ Branch 0 taken 2227 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2227 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 2221 times.
✓ Branch 6 taken 2227 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2227 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 2224 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
2233 if (!sctx->check_access(SUPER_ACL) &&
3964
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 !sctx->has_global_grant(STRING_WITH_LEN("GROUP_REPLICATION_ADMIN"))
3965
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 .first) {
3966
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0),
3967 "SUPER or GROUP_REPLICATION_ADMIN");
3968 141 goto error;
3969 }
3970
4/4
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 2197 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 25 times.
2224 if (lex->slave_connection.password && !lex->slave_connection.user) {
3971
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 my_error(ER_GROUP_REPLICATION_USER_MANDATORY_MSG, MYF(0));
3972 2 goto error;
3973 }
3974
3975 /*
3976 If the client thread has locked tables, a deadlock is possible.
3977 Assume that
3978 - the client thread does LOCK TABLE t READ.
3979 - then the client thread does START GROUP_REPLICATION.
3980 -try to make the server in super ready only mode
3981 -acquire MDL lock ownership which will be waiting for
3982 LOCK on table t to be released.
3983 To prevent that, refuse START GROUP_REPLICATION if the
3984 client thread has locked tables
3985 */
3986
6/6
✓ Branch 0 taken 2221 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2220 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2220 times.
4442 if (thd->locked_tables_mode || thd->in_active_multi_stmt_transaction() ||
3987
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2220 times.
2220 thd->in_sub_stmt) {
3988
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
3989 2 goto error;
3990 }
3991
3992
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2219 times.
2220 if (thd->variables.gtid_next.type == ASSIGNED_GTID &&
3993
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 thd->owned_gtid.sidno > 0) {
3994
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_CANT_EXECUTE_COMMAND_WITH_ASSIGNED_GTID_NEXT, MYF(0));
3995 1 early_error_on_rep_command = true;
3996 1 goto error;
3997 }
3998
3999
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2218 times.
2219 if (Clone_handler::is_provisioning()) {
4000
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_GROUP_REPLICATION_COMMAND_FAILURE, MYF(0),
4001 "START GROUP_REPLICATION",
4002 "This server is being provisioned by CLONE INSTANCE, "
4003 "please wait until it is complete.");
4004 1 goto error;
4005 }
4006
4007 2218 char *error_message = nullptr;
4008
9/12
✓ Branch 0 taken 2218 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 100 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 14 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 2086 times.
2218 res = group_replication_start(&error_message, thd);
4009
4010 // To reduce server dependency, server errors are not used here
4011 switch (res) {
4012 100 case 1: // GROUP_REPLICATION_CONFIGURATION_ERROR
4013
1/2
✓ Branch 0 taken 100 times.
✗ Branch 1 not taken.
100 my_error(ER_GROUP_REPLICATION_CONFIGURATION, MYF(0));
4014 100 goto error;
4015 5 case 2: // GROUP_REPLICATION_ALREADY_RUNNING
4016
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 my_error(ER_GROUP_REPLICATION_RUNNING, MYF(0));
4017 5 goto error;
4018 9 case 3: // GROUP_REPLICATION_REPLICATION_APPLIER_INIT_ERROR
4019
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 my_error(ER_GROUP_REPLICATION_APPLIER_INIT_ERROR, MYF(0));
4020 9 goto error;
4021 14 case 4: // GROUP_REPLICATION_COMMUNICATION_LAYER_SESSION_ERROR
4022
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 my_error(ER_GROUP_REPLICATION_COMMUNICATION_LAYER_SESSION_ERROR,
4023 MYF(0));
4024 14 goto error;
4025 1 case 5: // GROUP_REPLICATION_COMMUNICATION_LAYER_JOIN_ERROR
4026
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_GROUP_REPLICATION_COMMUNICATION_LAYER_JOIN_ERROR, MYF(0));
4027 1 goto error;
4028 case 7: // GROUP_REPLICATION_MAX_GROUP_SIZE
4029 my_error(ER_GROUP_REPLICATION_MAX_GROUP_SIZE, MYF(0));
4030 goto error;
4031 2 case 8: // GROUP_REPLICATION_COMMAND_FAILURE
4032
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (error_message == nullptr) {
4033 my_error(ER_GROUP_REPLICATION_COMMAND_FAILURE, MYF(0),
4034 "START GROUP_REPLICATION",
4035 "Please check error log for additional details.");
4036 } else {
4037
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 my_error(ER_GROUP_REPLICATION_COMMAND_FAILURE, MYF(0),
4038 "START GROUP_REPLICATION", error_message);
4039
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 my_free(error_message);
4040 }
4041 2 goto error;
4042 case 9: // GROUP_REPLICATION_SERVICE_MESSAGE_INIT_FAILURE
4043 my_error(ER_GRP_RPL_MESSAGE_SERVICE_INIT_FAILURE, MYF(0));
4044 goto error;
4045 1 case 10: // GROUP_REPLICATION_RECOVERY_CHANNEL_STILL_RUNNING
4046
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_GRP_RPL_RECOVERY_CHANNEL_STILL_RUNNING, MYF(0));
4047 1 goto error;
4048 }
4049
1/2
✓ Branch 0 taken 2086 times.
✗ Branch 1 not taken.
2086 my_ok(thd);
4050 2086 res = 0;
4051 2086 break;
4052 }
4053
4054 2053 case SQLCOM_STOP_GROUP_REPLICATION: {
4055 2053 Security_context *sctx = thd->security_context();
4056
8/16
✓ Branch 0 taken 2053 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2053 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 2047 times.
✓ Branch 6 taken 2053 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2053 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 2050 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
2059 if (!sctx->check_access(SUPER_ACL) &&
4057
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 !sctx->has_global_grant(STRING_WITH_LEN("GROUP_REPLICATION_ADMIN"))
4058
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 .first) {
4059
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0),
4060 "SUPER or GROUP_REPLICATION_ADMIN");
4061 17 goto error;
4062 }
4063
4064 /*
4065 Please see explanation @SQLCOM_SLAVE_STOP case
4066 to know the reason for thd->locked_tables_mode in
4067 the below if condition.
4068 */
4069
6/6
✓ Branch 0 taken 2049 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2048 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2048 times.
4098 if (thd->locked_tables_mode || thd->in_active_multi_stmt_transaction() ||
4070
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2048 times.
2048 thd->in_sub_stmt) {
4071
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
4072 2 goto error;
4073 }
4074
4075
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2047 times.
2048 if (thd->variables.gtid_next.type == ASSIGNED_GTID &&
4076
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 thd->owned_gtid.sidno > 0) {
4077
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_CANT_EXECUTE_COMMAND_WITH_ASSIGNED_GTID_NEXT, MYF(0));
4078 1 early_error_on_rep_command = true;
4079 1 goto error;
4080 }
4081
4082 2047 char *error_message = nullptr;
4083
1/2
✓ Branch 0 taken 2047 times.
✗ Branch 1 not taken.
2047 res = group_replication_stop(&error_message);
4084
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2040 times.
2047 if (res == 1) // GROUP_REPLICATION_CONFIGURATION_ERROR
4085 {
4086
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 my_error(ER_GROUP_REPLICATION_CONFIGURATION, MYF(0));
4087 7 goto error;
4088 }
4089
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2039 times.
2040 if (res == 6) // GROUP_REPLICATION_APPLIER_THREAD_TIMEOUT
4090 {
4091
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_GROUP_REPLICATION_STOP_APPLIER_THREAD_TIMEOUT, MYF(0));
4092 1 goto error;
4093 }
4094
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2036 times.
2039 if (res == 8) // GROUP_REPLICATION_COMMAND_FAILURE
4095 {
4096
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (error_message == nullptr) {
4097 my_error(ER_GROUP_REPLICATION_COMMAND_FAILURE, MYF(0),
4098 "STOP GROUP_REPLICATION",
4099 "Please check error log for additonal details.");
4100 } else {
4101
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 my_error(ER_GROUP_REPLICATION_COMMAND_FAILURE, MYF(0),
4102 "STOP GROUP_REPLICATION", error_message);
4103
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 my_free(error_message);
4104 }
4105 3 goto error;
4106 }
4107
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2035 times.
2036 if (res == 11) // GROUP_REPLICATION_STOP_WITH_RECOVERY_TIMEOUT
4108
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 push_warning(thd, Sql_condition::SL_WARNING,
4109 ER_GRP_RPL_RECOVERY_CHANNEL_STILL_RUNNING,
4110 ER_THD(thd, ER_GRP_RPL_RECOVERY_CHANNEL_STILL_RUNNING));
4111
4112 // Allow the command to commit any underlying transaction
4113 2036 lex->set_was_replication_command_executed();
4114 2036 thd->set_skip_readonly_check();
4115
1/2
✓ Branch 0 taken 2036 times.
✗ Branch 1 not taken.
2036 my_ok(thd);
4116 2036 res = 0;
4117 2036 break;
4118 }
4119
4120 7030 case SQLCOM_SLAVE_START: {
4121
1/2
✓ Branch 0 taken 7024 times.
✗ Branch 1 not taken.
7030 res = start_slave_cmd(thd);
4122 7024 break;
4123 }
4124 5884 case SQLCOM_SLAVE_STOP: {
4125 /*
4126 If the client thread has locked tables, a deadlock is possible.
4127 Assume that
4128 - the client thread does LOCK TABLE t READ.
4129 - then the master updates t.
4130 - then the SQL slave thread wants to update t,
4131 so it waits for the client thread because t is locked by it.
4132 - then the client thread does SLAVE STOP.
4133 SLAVE STOP waits for the SQL slave thread to terminate its
4134 update t, which waits for the client thread because t is locked by it.
4135 To prevent that, refuse SLAVE STOP if the
4136 client thread has locked tables
4137 */
4138
3/4
✓ Branch 0 taken 5884 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5881 times.
✓ Branch 3 taken 3 times.
11768 if (thd->locked_tables_mode || thd->in_active_multi_stmt_transaction() ||
4139
5/6
✓ Branch 0 taken 5884 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 5878 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 5878 times.
17652 thd->global_read_lock.is_acquired() ||
4140 5881 thd->backup_tables_lock.is_acquired()) {
4141
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
4142 6 goto error;
4143 }
4144
4145
1/2
✓ Branch 0 taken 5878 times.
✗ Branch 1 not taken.
5878 res = stop_slave_cmd(thd);
4146 5878 break;
4147 }
4148 10000 case SQLCOM_RENAME_TABLE: {
4149
2/4
✓ Branch 0 taken 10000 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10000 times.
✗ Branch 3 not taken.
10000 assert(first_table == all_tables && first_table != nullptr);
4150 TABLE_LIST *table;
4151
2/2
✓ Branch 0 taken 18476 times.
✓ Branch 1 taken 9959 times.
28435 for (table = first_table; table; table = table->next_local->next_local) {
4152
1/2
✓ Branch 0 taken 18476 times.
✗ Branch 1 not taken.
18476 if (check_access(thd, ALTER_ACL | DROP_ACL, table->db,
4153 &table->grant.privilege, &table->grant.m_internal,
4154
4/4
✓ Branch 0 taken 18443 times.
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 18443 times.
36919 false, false) ||
4155
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18443 times.
18443 check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db,
4156 18443 &table->next_local->grant.privilege,
4157
1/2
✓ Branch 0 taken 18443 times.
✗ Branch 1 not taken.
18443 &table->next_local->grant.m_internal, false, false))
4158 41 goto error;
4159
4160
1/2
✓ Branch 0 taken 18443 times.
✗ Branch 1 not taken.
18443 TABLE_LIST old_list = table[0];
4161
1/2
✓ Branch 0 taken 18443 times.
✗ Branch 1 not taken.
18443 TABLE_LIST new_list = table->next_local[0];
4162 /*
4163 It's not clear what the above assignments actually want to
4164 accomplish. What we do know is that they do *not* want to copy the MDL
4165 requests, so we overwrite them with uninitialized request.
4166 */
4167
1/2
✓ Branch 0 taken 18443 times.
✗ Branch 1 not taken.
18443 old_list.mdl_request = MDL_request();
4168
1/2
✓ Branch 0 taken 18443 times.
✗ Branch 1 not taken.
18443 new_list.mdl_request = MDL_request();
4169
4170
1/2
✓ Branch 0 taken 18443 times.
✗ Branch 1 not taken.
18443 if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, false, 1,
4171
4/4
✓ Branch 0 taken 18436 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 18435 times.
36879 false) ||
4172
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 18433 times.
18436 (!test_all_bits(table->next_local->grant.privilege,
4173 3 INSERT_ACL | CREATE_ACL) &&
4174
3/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2 times.
3 check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, false, 1,
4175 false)))
4176 8 goto error;
4177 }
4178
4179 #ifdef WITH_WSREP
4180
6/10
✓ Branch 0 taken 9959 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
✓ Branch 3 taken 9918 times.
✓ Branch 4 taken 41 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 41 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 9959 times.
10000 if (WSREP(thd) &&
4181
2/4
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 41 times.
41 wsrep_to_isolation_begin(thd, NULL, NULL, first_table)) {
4182 goto error;
4183 }
4184 #endif /* WITH_WSREP */
4185
4186
3/4
✓ Branch 0 taken 9915 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8337 times.
✓ Branch 3 taken 1578 times.
9959 if (mysql_rename_tables(thd, first_table)) goto error;
4187 1578 break;
4188 }
4189 25623 case SQLCOM_CHECKSUM: {
4190 #ifdef WITH_WSREP
4191
9/16
✓ Branch 0 taken 25623 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1679 times.
✓ Branch 3 taken 23944 times.
✓ Branch 4 taken 1679 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1679 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1679 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1679 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 1679 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 25623 times.
25623 WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_READ);
4192 #endif /* WITH_WSREP */
4193
2/4
✓ Branch 0 taken 25623 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25623 times.
✗ Branch 3 not taken.
25623 assert(first_table == all_tables && first_table != nullptr);
4194
3/4
✓ Branch 0 taken 25623 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 25621 times.
25623 if (check_table_access(thd, SELECT_ACL, all_tables, false, UINT_MAX,
4195 false))
4196 2 goto error; /* purecov: inspected */
4197
4198
1/2
✓ Branch 0 taken 25621 times.
✗ Branch 1 not taken.
25621 res = mysql_checksum_table(thd, first_table, &lex->check_opt);
4199 25621 break;
4200 }
4201 7894225 case SQLCOM_REPLACE:
4202 case SQLCOM_INSERT:
4203 case SQLCOM_REPLACE_SELECT:
4204 case SQLCOM_INSERT_SELECT:
4205 #ifdef WITH_WSREP
4206 {
4207
13/16
✓ Branch 0 taken 7894222 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1900471 times.
✓ Branch 3 taken 5993751 times.
✓ Branch 4 taken 31599 times.
✓ Branch 5 taken 1868872 times.
✓ Branch 6 taken 19858 times.
✓ Branch 7 taken 11741 times.
✓ Branch 8 taken 19813 times.
✓ Branch 9 taken 45 times.
✓ Branch 10 taken 19793 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 19793 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 7894205 times.
7894225 WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_INSERT_REPLACE);
4208
2/4
✓ Branch 0 taken 7894297 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7894491 times.
✗ Branch 3 not taken.
7894205 assert(first_table == all_tables && first_table != 0);
4209
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7894491 times.
7894491 assert(lex->m_sql_cmd != NULL);
4210
1/2
✓ Branch 0 taken 7895110 times.
✗ Branch 1 not taken.
7894491 res = lex->m_sql_cmd->execute(thd);
4211 7895110 break;
4212 }
4213 #endif /* WITH_WSREP */
4214 352708 case SQLCOM_DELETE:
4215 case SQLCOM_DELETE_MULTI:
4216 case SQLCOM_UPDATE:
4217 case SQLCOM_UPDATE_MULTI:
4218 #ifdef WITH_WSREP
4219 {
4220
13/16
✓ Branch 0 taken 352705 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 24830 times.
✓ Branch 3 taken 327875 times.
✓ Branch 4 taken 16456 times.
✓ Branch 5 taken 8374 times.
✓ Branch 6 taken 10870 times.
✓ Branch 7 taken 5586 times.
✓ Branch 8 taken 10868 times.
✓ Branch 9 taken 2 times.
✓ Branch 10 taken 10868 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 10868 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 352708 times.
352708 WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE);
4221
3/4
✓ Branch 0 taken 352707 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 352716 times.
✗ Branch 3 not taken.
352708 assert(first_table == all_tables && first_table != 0);
4222
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 352716 times.
352716 assert(lex->m_sql_cmd != NULL);
4223
1/2
✓ Branch 0 taken 352787 times.
✗ Branch 1 not taken.
352716 res = lex->m_sql_cmd->execute(thd);
4224 352787 break;
4225 }
4226 #endif /* WITH_WSREP */
4227 678214 case SQLCOM_CREATE_TABLE:
4228 case SQLCOM_CREATE_INDEX:
4229 case SQLCOM_DROP_INDEX:
4230 case SQLCOM_ASSIGN_TO_KEYCACHE:
4231 case SQLCOM_PRELOAD_KEYS:
4232 case SQLCOM_LOAD: {
4233
2/4
✓ Branch 0 taken 678214 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 678214 times.
✗ Branch 3 not taken.
678214 assert(first_table == all_tables && first_table != nullptr);
4234
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 678214 times.
678214 assert(lex->m_sql_cmd != nullptr);
4235
1/2
✓ Branch 0 taken 678177 times.
✗ Branch 1 not taken.
678214 res = lex->m_sql_cmd->execute(thd);
4236 678177 break;
4237 }
4238 160725 case SQLCOM_DROP_TABLE: {
4239
2/4
✓ Branch 0 taken 160725 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 160725 times.
✗ Branch 3 not taken.
160725 assert(first_table == all_tables && first_table != nullptr);
4240
2/2
✓ Branch 0 taken 153464 times.
✓ Branch 1 taken 7261 times.
160725 if (!lex->drop_temporary) {
4241
3/4
✓ Branch 0 taken 153464 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 153455 times.
153464 if (check_table_access(thd, DROP_ACL, all_tables, false, UINT_MAX,
4242 false))
4243 9 goto error; /* purecov: inspected */
4244 }
4245
4246
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 160692 times.
160716 if (thd->variables.binlog_ddl_skip_rewrite) {
4247 24 size_t table_count = 0;
4248
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 18 times.
48 for (TABLE_LIST *table = all_tables; table; table = table->next_local) {
4249 30 ++table_count;
4250
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 24 times.
30 if (table_count > 1) {
4251 /*
4252 When 'binlog_ddl_skip_rewrite' option is enabled, logging query
4253 without rewrite does not not work as expected if tables contain
4254 both normal tables and temporary tables,consider these two cases.
4255 Case1: Statements like 'drop table t1,t2' where t1 is a normal
4256 table and t2 is a temporary table, will fail on the slave because
4257 temporary table will not be present on the slave.
4258 Case2: Statements like 'DROP TABLE t1 / *!80024 ,t2 * /' will
4259 generate single table or multi table drop statements depending
4260 on the mysql version.
4261 */
4262
4263
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 my_error(ER_DROP_MULTI_TABLE, MYF(0), "binlog_ddl_skip_rewrite");
4264 6 goto error;
4265 }
4266 }
4267 }
4268
4269 #ifdef WITH_WSREP
4270
2/2
✓ Branch 0 taken 161185 times.
✓ Branch 1 taken 37764 times.
198949 for (TABLE_LIST *table = all_tables; table; table = table->next_global) {
4271
6/6
✓ Branch 0 taken 153509 times.
✓ Branch 1 taken 7676 times.
✓ Branch 2 taken 134291 times.
✓ Branch 3 taken 19218 times.
✓ Branch 4 taken 122946 times.
✓ Branch 5 taken 38239 times.
448985 if (!lex->drop_temporary &&
4272 153509 (!thd->is_current_stmt_binlog_format_row() ||
4273
3/4
✓ Branch 0 taken 134291 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103728 times.
✓ Branch 3 taken 30563 times.
134291 !find_temporary_table(thd, table))) {
4274 122946 wsrep::key_array keys;
4275
3/4
✓ Branch 0 taken 122946 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 122944 times.
122946 if (wsrep_append_fk_parent_table(thd, all_tables, &keys)) {
4276 2 return true;
4277 }
4278
11/16
✓ Branch 0 taken 122944 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17497 times.
✓ Branch 3 taken 105447 times.
✓ Branch 4 taken 3663 times.
✓ Branch 5 taken 13834 times.
✓ Branch 6 taken 3661 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 3661 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3661 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 3661 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 122944 times.
122944 WSREP_TO_ISOLATION_BEGIN_FK_TABLES_IF(NULL, NULL, all_tables, &keys) {
4279 goto error;
4280 }
4281 122944 break;
4282
2/3
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 122944 times.
122946 }
4283 }
4284 #endif /* WITH_WSREP */
4285
4286 /* DDL and binlog write order are protected by metadata locks. */
4287 321392 res = mysql_rm_table(thd, first_table, lex->drop_if_exists,
4288
1/2
✓ Branch 0 taken 160684 times.
✗ Branch 1 not taken.
160708 lex->drop_temporary);
4289 /* when dropping temporary tables if @@session_track_state_change is ON
4290 then send the boolean tracker in the OK packet */
4291
4/4
✓ Branch 0 taken 156712 times.
✓ Branch 1 taken 3972 times.
✓ Branch 2 taken 7167 times.
✓ Branch 3 taken 149545 times.
160684 if (!res && lex->drop_temporary) {
4292
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7160 times.
7167 if (thd->session_tracker.get_tracker(SESSION_STATE_CHANGE_TRACKER)
4293
1/2
✓ Branch 0 taken 7167 times.
✗ Branch 1 not taken.
7167 ->is_enabled())
4294
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 thd->session_tracker.get_tracker(SESSION_STATE_CHANGE_TRACKER)
4295
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 ->mark_as_changed(thd, {});
4296 }
4297 160684 } break;
4298 89892 case SQLCOM_CHANGE_DB: {
4299 89892 const LEX_CSTRING db_str = {query_block->db, strlen(query_block->db)};
4300
4301
4/6
✓ Branch 0 taken 89892 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 89867 times.
✓ Branch 3 taken 25 times.
✓ Branch 4 taken 89867 times.
✗ Branch 5 not taken.
89892 if (!mysql_change_db(thd, db_str, false)) my_ok(thd);
4302
4303 89892 break;
4304 }
4305
4306 1504619 case SQLCOM_SET_OPTION: {
4307 1504619 List<set_var_base> *lex_var_list = &lex->var_list;
4308
4309 #ifdef WITH_WSREP
4310 1504619 ulong cached_pxc_maint_mode = pxc_maint_mode;
4311
4312 1504619 ulong cached_osu_method = WSREP_OSU_NONE;
4313
6/8
✓ Branch 0 taken 39905 times.
✓ Branch 1 taken 1464714 times.
✓ Branch 2 taken 39905 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 39905 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 39905 times.
✓ Branch 7 taken 1464714 times.
1504619 if (thd->variables.wsrep_on && wsrep_thd_is_local(thd)) {
4314 39905 cached_osu_method = thd->variables.wsrep_OSU_method;
4315 }
4316 #endif /* WITH_WSREP */
4317
4318
3/4
✓ Branch 0 taken 1504653 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1504650 times.
1504619 if (check_table_access(thd, SELECT_ACL, all_tables, false, UINT_MAX,
4319 false))
4320 3 goto error;
4321
4322
3/4
✓ Branch 0 taken 1504587 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 116 times.
✓ Branch 3 taken 1504471 times.
1504650 if (open_tables_for_query(thd, all_tables, false)) goto error;
4323
2/2
✓ Branch 0 taken 509647 times.
✓ Branch 1 taken 994852 times.
1504471 if (!thd->stmt_arena->is_regular()) {
4324
1/2
✓ Branch 0 taken 509664 times.
✗ Branch 1 not taken.
509647 lex->restore_cmd_properties();
4325
1/2
✓ Branch 0 taken 509677 times.
✗ Branch 1 not taken.
509664 bind_fields(thd->stmt_arena->item_list());
4326 509808 if (all_tables != nullptr &&
4327
6/6
✓ Branch 0 taken 130 times.
✓ Branch 1 taken 509547 times.
✓ Branch 2 taken 106 times.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 509677 times.
509784 !thd->stmt_arena->is_stmt_prepare_or_first_stmt_execute() &&
4328
3/4
✓ Branch 0 taken 107 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 106 times.
106 query_block->check_privileges_for_subqueries(thd))
4329 1 return true;
4330 }
4331
3/4
✓ Branch 0 taken 1504134 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1497712 times.
✓ Branch 3 taken 6422 times.
1504529 if (!(res = sql_set_variables(thd, lex_var_list, true)))
4332
1/2
✓ Branch 0 taken 1497923 times.
✗ Branch 1 not taken.
1497712 my_ok(thd);
4333 else {
4334 /*
4335 We encountered some sort of error, but no message was sent.
4336 Send something semi-generic here since we don't know which
4337 assignment in the list caused the error.
4338 */
4339
4/6
✓ Branch 0 taken 6445 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 6443 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
6422 if (!thd->is_error()) my_error(ER_WRONG_ARGUMENTS, MYF(0), "SET");
4340 6445 goto error;
4341 }
4342
4343 #ifdef WITH_WSREP
4344
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1497919 times.
1497923 if (cached_pxc_maint_mode != pxc_maint_mode &&
4345
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 pxc_maint_mode == PXC_MAINT_MODE_MAINTENANCE) {
4346
10/22
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2 WSREP_INFO("Sleep for %lu secs while switching to maintenance mode",
4347 pxc_maint_transition_period);
4348
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
2 sleep(pxc_maint_transition_period);
4349 }
4350
4351
6/8
✓ Branch 0 taken 63031 times.
✓ Branch 1 taken 1434691 times.
✓ Branch 2 taken 63031 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 63031 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 63031 times.
✓ Branch 7 taken 1434691 times.
1497722 if (thd->variables.wsrep_on && wsrep_thd_is_local(thd)) {
4352 63031 ulong osu_method = thd->variables.wsrep_OSU_method;
4353 /* OSU method set to RSU.
4354 Commit/Rollback existing transaction (if any) */
4355
4/4
✓ Branch 0 taken 36998 times.
✓ Branch 1 taken 26033 times.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 36978 times.
63031 if (cached_osu_method == WSREP_OSU_TOI && osu_method == WSREP_OSU_RSU) {
4356
2/4
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
20 if (trans_commit_implicit(thd)) {
4357 thd->mdl_context.release_transactional_locks();
4358 WSREP_DEBUG(
4359 "Transaction implicit commit failed"
4360 " MDL released: %u",
4361 thd->thread_id());
4362 return -1;
4363 }
4364
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 thd->mdl_context.release_transactional_locks();
4365
5/10
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 20 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 20 times.
20 if (wsrep_thd_is_local(thd) && wsrep_after_statement(thd)) {
4366 return -1;
4367 }
4368 }
4369 }
4370 #endif /* WITH_WSREP */
4371
4372 #ifndef NDEBUG
4373 /*
4374 Makes server crash when executing SET SESSION debug = 'd,crash_now';
4375 See mysql-test/include/dbug_crash[_all].inc
4376 */
4377 1497722 const bool force_server_crash_dbug = false;
4378
2/4
✓ Branch 0 taken 1497628 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1497628 times.
1497722 DBUG_EXECUTE_IF("crash_now", assert(force_server_crash_dbug););
4379
4/6
✓ Branch 0 taken 1497751 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 1497736 times.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
1497628 DBUG_EXECUTE_IF("crash_now_safe", DBUG_SUICIDE(););
4380 #endif
4381
4382 1497736 break;
4383 }
4384 922 case SQLCOM_SET_PASSWORD: {
4385 922 List<set_var_base> *lex_var_list = &lex->var_list;
4386
4387
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 922 times.
922 assert(lex_var_list->elements == 1);
4388
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 922 times.
922 assert(all_tables == nullptr);
4389 922 Userhostpassword_list generated_passwords;
4390
3/4
✓ Branch 0 taken 920 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 688 times.
✓ Branch 3 taken 232 times.
922 if (!(res = sql_set_variables(thd, lex_var_list, false))) {
4391
1/2
✓ Branch 0 taken 688 times.
✗ Branch 1 not taken.
688 List_iterator_fast<set_var_base> it(*lex_var_list);
4392 set_var_base *var;
4393
2/2
✓ Branch 0 taken 688 times.
✓ Branch 1 taken 688 times.
1376 while ((var = it++)) {
4394 688 set_var_password *setpasswd = static_cast<set_var_password *>(var);
4395
2/2
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 635 times.
688 if (setpasswd->has_generated_password()) {
4396 53 const LEX_USER *user = setpasswd->get_user();
4397 53 random_password_info p{
4398 53 std::string(user->user.str, user->user.length),
4399 53 std::string(user->host.str, user->host.length),
4400
3/6
✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 53 times.
✗ Branch 5 not taken.
53 setpasswd->get_generated_password(), 1};
4401
1/2
✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
53 generated_passwords.push_back(p);
4402 53 }
4403 }
4404
2/2
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 635 times.
688 if (generated_passwords.size() > 0) {
4405
2/4
✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53 times.
53 if (send_password_result_set(thd, generated_passwords)) goto error;
4406 } // end if generated_passwords
4407
3/4
✓ Branch 0 taken 635 times.
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 635 times.
✗ Branch 3 not taken.
688 if (generated_passwords.size() == 0) my_ok(thd);
4408 } else {
4409 // We encountered some sort of error, but no message was sent.
4410
2/4
✓ Branch 0 taken 232 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 232 times.
232 if (!thd->is_error())
4411 my_error(ER_WRONG_ARGUMENTS, MYF(0), "SET PASSWORD");
4412 232 goto error;
4413 }
4414
4415 688 break;
4416
2/2
✓ Branch 0 taken 232 times.
✓ Branch 1 taken 688 times.
920 }
4417
4418 4453 case SQLCOM_UNLOCK_TABLES: {
4419 #ifdef WITH_WSREP
4420 /* UNLOCK Tables is generic statement and not all lock table variants
4421 are blocked (only one with explict table lock are blocked). */
4422 4453 bool table_lock = (thd->variables.option_bits & OPTION_TABLE_LOCK);
4423 #endif /* WITH_WSREP */
4424
4425 /*
4426 It is critical for mysqldump --single-transaction --source-data that
4427 UNLOCK TABLES does not implicitly commit a connection which has only
4428 done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
4429 false, mysqldump will not work.
4430 */
4431
2/2
✓ Branch 0 taken 2873 times.
✓ Branch 1 taken 1580 times.
4453 if (thd->variables.option_bits & OPTION_TABLE_LOCK) {
4432
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2873 times.
2873 assert(!thd->backup_tables_lock.is_acquired());
4433 /*
4434 Can we commit safely? If not, return to avoid releasing
4435 transactional metadata locks.
4436 */
4437
2/4
✓ Branch 0 taken 2873 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2873 times.
2873 if (trans_check_state(thd)) return -1;
4438
1/2
✓ Branch 0 taken 2873 times.
✗ Branch 1 not taken.
2873 res = trans_commit_implicit(thd);
4439
1/2
✓ Branch 0 taken 2873 times.
✗ Branch 1 not taken.
2873 thd->locked_tables_list.unlock_locked_tables(thd);
4440
1/2
✓ Branch 0 taken 2873 times.
✗ Branch 1 not taken.
2873 thd->mdl_context.release_transactional_locks();
4441 2873 thd->variables.option_bits &= ~(OPTION_TABLE_LOCK);
4442 }
4443
4444
2/2
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 4201 times.
4453 if (thd->backup_tables_lock.is_acquired()) {
4445
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 252 times.
252 assert(!(thd->variables.option_bits & OPTION_TABLE_LOCK));
4446
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 252 times.
252 assert(!thd->global_read_lock.is_acquired());
4447
4448 252 thd->backup_tables_lock.release(thd);
4449 }
4450
4451
2/2
✓ Branch 0 taken 584 times.
✓ Branch 1 taken 3869 times.
4453 if (thd->global_read_lock.is_acquired())
4452
1/2
✓ Branch 0 taken 584 times.
✗ Branch 1 not taken.
584 thd->global_read_lock.unlock_global_read_lock(thd);
4453
4454 #ifdef WITH_WSREP
4455 /*
4456 This is for resuming the provider when used for
4457 FLUSH TABLES <table> WITH READ LOCK or
4458 FLUSH TABLES <table> FOR EXPORT.
4459 Note, the return value for resume is ignored here because
4460 we don't want to fail the query if provider is already resumed.
4461
4462 Also, note that this is done after GRL is unlocked.
4463 This is important because provider is resumed there
4464 and we don't want do it again.
4465 */
4466
9/12
✓ Branch 0 taken 4453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 370 times.
✓ Branch 3 taken 4083 times.
✓ Branch 4 taken 370 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 364 times.
✓ Branch 7 taken 6 times.
✓ Branch 8 taken 86 times.
✓ Branch 9 taken 278 times.
✓ Branch 10 taken 86 times.
✗ Branch 11 not taken.
4453 if (WSREP(thd) && table_lock) thd->global_read_lock.wsrep_resume_once();
4467 #endif /* WITH_WSREP */
4468
4469
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4452 times.
4453 if (res) goto error;
4470
1/2
✓ Branch 0 taken 4452 times.
✗ Branch 1 not taken.
4452 my_ok(thd);
4471 4452 break;
4472 }
4473
4474 2867 case SQLCOM_LOCK_TABLES:
4475
4476 #ifdef WITH_WSREP
4477
3/4
✓ Branch 0 taken 2867 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2865 times.
2867 if (pxc_strict_mode_lock_check(thd)) goto error;
4478 #endif /* WITH_WSREP */
4479
4480 /*
4481 Do not allow LOCK TABLES under an active LOCK TABLES FOR BACKUP in the
4482 same connection.
4483 */
4484
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2865 times.
2865 if (thd->backup_tables_lock.abort_if_acquired()) goto error;
4485
4486 /*
4487 Can we commit safely? If not, return to avoid releasing
4488 transactional metadata locks.
4489 */
4490
2/4
✓ Branch 0 taken 2865 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2865 times.
2865 if (trans_check_state(thd)) return -1;
4491 /* We must end the transaction first, regardless of anything */
4492
1/2
✓ Branch 0 taken 2865 times.
✗ Branch 1 not taken.
2865 res = trans_commit_implicit(thd);
4493
1/2
✓ Branch 0 taken 2865 times.
✗ Branch 1 not taken.
2865 thd->locked_tables_list.unlock_locked_tables(thd);
4494 /* Release transactional metadata locks. */
4495
1/2
✓ Branch 0 taken 2865 times.
✗ Branch 1 not taken.
2865 thd->mdl_context.release_transactional_locks();
4496
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2865 times.
2865 if (res) goto error;
4497
4498 /*
4499 Here we have to pre-open temporary tables for LOCK TABLES.
4500
4501 CF_PREOPEN_TMP_TABLES is not set for this SQL statement simply
4502 because LOCK TABLES calls close_thread_tables() as a first thing
4503 (it's called from unlock_locked_tables() above). So even if
4504 CF_PREOPEN_TMP_TABLES was set and the tables would be pre-opened
4505 in a usual way, they would have been closed.
4506 */
4507
4508
3/4
✓ Branch 0 taken 2865 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2864 times.
2865 if (open_temporary_tables(thd, all_tables)) goto error;
4509
4510
3/4
✓ Branch 0 taken 2864 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 245 times.
✓ Branch 3 taken 2619 times.
2864 if (lock_tables_precheck(thd, all_tables)) goto error;
4511
4512 2619 thd->variables.option_bits |= OPTION_TABLE_LOCK;
4513
4514
1/2
✓ Branch 0 taken 2619 times.
✗ Branch 1 not taken.
2619 res = lock_tables_open_and_lock_tables(thd, all_tables);
4515
4516
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 2564 times.
2619 if (res) {
4517 55 thd->variables.option_bits &= ~(OPTION_TABLE_LOCK);
4518 } else {
4519
1/2
✓ Branch 0 taken 2564 times.
✗ Branch 1 not taken.
2564 my_ok(thd);
4520 }
4521 2619 break;
4522
4523 35 case SQLCOM_IMPORT:
4524
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
35 res = lex->m_sql_cmd->execute(thd);
4525 35 break;
4526
4527 254 case SQLCOM_LOCK_TABLES_FOR_BACKUP:
4528
3/6
✓ Branch 0 taken 254 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 254 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 254 times.
✗ Branch 5 not taken.
254 if (!lock_tables_for_backup(thd)) my_ok(thd);
4529
4530 254 break;
4531 79 case SQLCOM_CREATE_COMPRESSION_DICTIONARY: {
4532 #ifdef WITH_WSREP
4533
8/14
✓ Branch 0 taken 79 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 75 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 4 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 79 times.
79 WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
4534 #endif /* WITH_WSREP */
4535
4536
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 58 times.
79 if (lex->create_info->zip_dict_name->fixed == 0)
4537
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 lex->create_info->zip_dict_name->fix_fields(thd, 0);
4538 79 String dict_data;
4539 String *dict_data_ptr =
4540
1/2
✓ Branch 0 taken 79 times.
✗ Branch 1 not taken.
79 lex->create_info->zip_dict_name->val_str_ascii(&dict_data);
4541
3/6
✓ Branch 0 taken 79 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 79 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 79 times.
79 if (dict_data_ptr == nullptr || dict_data_ptr->ptr() == nullptr) {
4542 dict_data.set("", 0, &my_charset_bin);
4543 dict_data_ptr = &dict_data;
4544 }
4545
4546 237 if ((res = compression_dict::create_zip_dict(
4547
1/2
✓ Branch 0 taken 79 times.
✗ Branch 1 not taken.
79 thd, lex->ident.str, lex->ident.length, dict_data_ptr->ptr(),
4548 dict_data_ptr->length(),
4549 79 (lex->create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) != 0,
4550
2/2
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 8 times.
79 false)) == 0)
4551
1/2
✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
71 my_ok(thd);
4552 79 break;
4553 79 }
4554 90 case SQLCOM_DROP_COMPRESSION_DICTIONARY: {
4555 #ifdef WITH_WSREP
4556
8/14
✓ Branch 0 taken 90 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 86 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 4 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 90 times.
90 WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
4557 #endif /* WITH_WSREP */
4558
4559 180 if ((res = compression_dict::drop_zip_dict(
4560
3/4
✓ Branch 0 taken 90 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 76 times.
✓ Branch 3 taken 14 times.
90 thd, lex->ident.str, lex->ident.length, lex->drop_if_exists)) ==
4561 0)
4562
1/2
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
76 my_ok(thd);
4563 90 break;
4564 }
4565 15607 case SQLCOM_CREATE_DB: {
4566 const char *alias;
4567
4/6
✓ Branch 0 taken 15607 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15607 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 15602 times.
31214 if (!(alias = thd->strmake(lex->name.str, lex->name.length)) ||
4568
3/4
✓ Branch 0 taken 15607 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 15602 times.
15607 (check_and_convert_db_name(&lex->name, false) !=
4569 Ident_name_check::OK))
4570 15603 break;
4571
3/4
✓ Branch 0 taken 15602 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 15591 times.
15602 if (check_access(thd, CREATE_ACL, lex->name.str, nullptr, nullptr, true,
4572 false))
4573 11 break;
4574
4575 #ifdef WITH_WSREP
4576
10/14
✓ Branch 0 taken 15591 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9902 times.
✓ Branch 3 taken 5689 times.
✓ Branch 4 taken 606 times.
✓ Branch 5 taken 9296 times.
✓ Branch 6 taken 153 times.
✓ Branch 7 taken 453 times.
✓ Branch 8 taken 153 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 153 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 15591 times.
15591 WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL, NULL)
4577 #endif /* WITH_WSREP */
4578 /*
4579 As mysql_create_db() may modify HA_CREATE_INFO structure passed to
4580 it, we need to use a copy of LEX::create_info to make execution
4581 prepared statement- safe.
4582 */
4583
1/2
✓ Branch 0 taken 15591 times.
✗ Branch 1 not taken.
15591 HA_CREATE_INFO create_info(*lex->create_info);
4584
1/2
✓ Branch 0 taken 15586 times.
✗ Branch 1 not taken.
15591 res = mysql_create_db(
4585
1/2
✓ Branch 0 taken 15591 times.
✗ Branch 1 not taken.
15591 thd, (lower_case_table_names == 2 ? alias : lex->name.str),
4586 &create_info);
4587 15586 break;
4588 15586 }
4589 6136 case SQLCOM_DROP_DB: {
4590
3/4
✓ Branch 0 taken 6136 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 6134 times.
6136 if (check_and_convert_db_name(&lex->name, false) != Ident_name_check::OK)
4591 2 break;
4592
3/4
✓ Branch 0 taken 6134 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 6120 times.
6134 if (check_access(thd, DROP_ACL, lex->name.str, nullptr, nullptr, true,
4593 false))
4594 14 break;
4595 #ifdef WITH_WSREP
4596
9/14
✓ Branch 0 taken 6120 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 244 times.
✓ Branch 3 taken 5876 times.
✓ Branch 4 taken 145 times.
✓ Branch 5 taken 99 times.
✓ Branch 6 taken 145 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 145 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 145 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 6120 times.
6120 WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL, NULL)
4597 #endif /* WITH_WSREP */
4598
1/2
✓ Branch 0 taken 6117 times.
✗ Branch 1 not taken.
6120 res = mysql_rm_db(thd, to_lex_cstring(lex->name), lex->drop_if_exists);
4599 6117 break;
4600 }
4601 975 case SQLCOM_ALTER_DB: {
4602
3/4
✓ Branch 0 taken 975 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 973 times.
975 if (check_and_convert_db_name(&lex->name, false) != Ident_name_check::OK)
4603 972 break;
4604
3/4
✓ Branch 0 taken 973 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 968 times.
973 if (check_access(thd, ALTER_ACL, lex->name.str, nullptr, nullptr, true,
4605 false))
4606 5 break;
4607 #ifdef WITH_WSREP
4608
9/14
✓ Branch 0 taken 968 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 211 times.
✓ Branch 3 taken 757 times.
✓ Branch 4 taken 26 times.
✓ Branch 5 taken 185 times.
✓ Branch 6 taken 26 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 26 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 26 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 968 times.
968 WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL, NULL)
4609 #endif /* WITH_WSREP */
4610 /*
4611 As mysql_alter_db() may modify HA_CREATE_INFO structure passed to
4612 it, we need to use a copy of LEX::create_info to make execution
4613 prepared statement- safe.
4614 */
4615
1/2
✓ Branch 0 taken 968 times.
✗ Branch 1 not taken.
968 HA_CREATE_INFO create_info(*lex->create_info);
4616
1/2
✓ Branch 0 taken 965 times.
✗ Branch 1 not taken.
968 res = mysql_alter_db(thd, lex->name.str, &create_info);
4617 965 break;
4618 965 }
4619 1142 case SQLCOM_CREATE_EVENT:
4620 case SQLCOM_ALTER_EVENT:
4621 do {
4622
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1142 times.
1142 assert(lex->event_parse_data);
4623
3/4
✓ Branch 0 taken 1142 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 1134 times.
1142 if (lex->table_or_sp_used()) {
4624
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 my_error(ER_NOT_SUPPORTED_YET, MYF(0),
4625 "Usage of subqueries or stored "
4626 "function calls as part of this statement");
4627 8 break;
4628 }
4629
4630
1/2
✓ Branch 0 taken 1134 times.
✗ Branch 1 not taken.
1134 res = sp_process_definer(thd);
4631
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1131 times.
1134 if (res) break;
4632
4633
2/3
✓ Branch 0 taken 930 times.
✓ Branch 1 taken 201 times.
✗ Branch 2 not taken.
1131 switch (lex->sql_command) {
4634 930 case SQLCOM_CREATE_EVENT: {
4635 930 bool if_not_exists =
4636 930 (lex->create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS);
4637 924 res =
4638
1/2
✓ Branch 0 taken 924 times.
✗ Branch 1 not taken.
930 Events::create_event(thd, lex->event_parse_data, if_not_exists);
4639 924 break;
4640 }
4641 201 case SQLCOM_ALTER_EVENT: {
4642 201 LEX_CSTRING name_lex_str = NULL_CSTR;
4643
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 170 times.
201 if (lex->spname) {
4644 31 name_lex_str.str = lex->spname->m_name.str;
4645 31 name_lex_str.length = lex->spname->m_name.length;
4646 }
4647
4648 195 res =
4649
1/2
✓ Branch 0 taken 195 times.
✗ Branch 1 not taken.
402 Events::update_event(thd, lex->event_parse_data,
4650
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 170 times.
201 lex->spname ? &lex->spname->m_db : nullptr,
4651
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 170 times.
201 lex->spname ? &name_lex_str : nullptr);
4652 195 break;
4653 }
4654 default:
4655 assert(0);
4656 }
4657
3/8
✓ Branch 0 taken 1119 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1119 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1119 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1119 DBUG_PRINT("info", ("DDL error code=%d", res));
4658
7/8
✓ Branch 0 taken 1039 times.
✓ Branch 1 taken 80 times.
✓ Branch 2 taken 1032 times.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 1032 times.
✓ Branch 5 taken 87 times.
✓ Branch 6 taken 1032 times.
✗ Branch 7 not taken.
1119 if (!res && !thd->killed) my_ok(thd);
4659
4660 } while (false);
4661 /* Don't do it, if we are inside a SP */
4662
2/2
✓ Branch 0 taken 1109 times.
✓ Branch 1 taken 21 times.
1130 if (!thd->sp_runtime_ctx) {
4663
1/2
✓ Branch 0 taken 1109 times.
✗ Branch 1 not taken.
1109 sp_head::destroy(lex->sphead);
4664 1109 lex->sphead = nullptr;
4665 }
4666 /* lex->cleanup() is called outside, no need to call it here */
4667 1130 break;
4668 500 case SQLCOM_DROP_EVENT: {
4669
3/4
✓ Branch 0 taken 494 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 474 times.
✓ Branch 3 taken 20 times.
500 if (!(res = Events::drop_event(thd, lex->spname->m_db,
4670 500 to_lex_cstring(lex->spname->m_name),
4671 500 lex->drop_if_exists)))
4672
1/2
✓ Branch 0 taken 474 times.
✗ Branch 1 not taken.
474 my_ok(thd);
4673 494 break;
4674 }
4675 205 case SQLCOM_CREATE_FUNCTION: // UDF function
4676 {
4677
3/4
✓ Branch 0 taken 205 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 204 times.
205 if (check_access(thd, INSERT_ACL, "mysql", nullptr, nullptr, true, false))
4678 1 break;
4679 #ifdef WITH_WSREP
4680
8/14
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 202 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 204 times.
204 WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
4681 #endif /* WITH_WSREP */
4682
2/2
✓ Branch 0 taken 188 times.
✓ Branch 1 taken 10 times.
198 if (!(res = mysql_create_function(
4683 thd, &lex->udf,
4684
1/2
✓ Branch 0 taken 198 times.
✗ Branch 1 not taken.
204 lex->create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)))
4685
1/2
✓ Branch 0 taken 188 times.
✗ Branch 1 not taken.
188 my_ok(thd);
4686 198 break;
4687 }
4688 6788 case SQLCOM_CREATE_USER: {
4689
1/2
✓ Branch 0 taken 6788 times.
✗ Branch 1 not taken.
6788 if (check_access(thd, INSERT_ACL, "mysql", nullptr, nullptr, true,
4690
4/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 6775 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6782 times.
6801 true) &&
4691
3/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 7 times.
13 check_global_access(thd, CREATE_USER_ACL))
4692 6 break;
4693 /* Conditionally writes to binlog */
4694
1/2
✓ Branch 0 taken 6782 times.
✗ Branch 1 not taken.
6782 HA_CREATE_INFO create_info(*lex->create_info);
4695 6776 if (!(res = mysql_create_user(
4696 6782 thd, lex->users_list,
4697
1/2
✓ Branch 0 taken 6776 times.
✗ Branch 1 not taken.
6782 create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS, false))) {
4698 // OK or result set was already sent.
4699 }
4700
4701 6776 break;
4702 6776 }
4703 5621 case SQLCOM_DROP_USER: {
4704
1/2
✓ Branch 0 taken 5621 times.
✗ Branch 1 not taken.
5621 if (check_access(thd, DELETE_ACL, "mysql", nullptr, nullptr, true,
4705
4/4
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 5610 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 5617 times.
5632 true) &&
4706
3/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 7 times.
11 check_global_access(thd, CREATE_USER_ACL))
4707 4 break;
4708 /* Conditionally writes to binlog */
4709
3/4
✓ Branch 0 taken 5609 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5405 times.
✓ Branch 3 taken 204 times.
5617 if (!(res = mysql_drop_user(thd, lex->users_list, lex->drop_if_exists,
4710 false)))
4711
1/2
✓ Branch 0 taken 5405 times.
✗ Branch 1 not taken.
5405 my_ok(thd);
4712
4713 5609 break;
4714 }
4715 523 case SQLCOM_RENAME_USER: {
4716
1/2
✓ Branch 0 taken 523 times.
✗ Branch 1 not taken.
523 if (check_access(thd, UPDATE_ACL, "mysql", nullptr, nullptr, true,
4717
4/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 509 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 520 times.
537 true) &&
4718
3/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 11 times.
14 check_global_access(thd, CREATE_USER_ACL))
4719 3 break;
4720 /* Conditionally writes to binlog */
4721
4/6
✓ Branch 0 taken 514 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 412 times.
✓ Branch 3 taken 102 times.
✓ Branch 4 taken 412 times.
✗ Branch 5 not taken.
520 if (!(res = mysql_rename_user(thd, lex->users_list))) my_ok(thd);
4722 514 break;
4723 }
4724 1698 case SQLCOM_REVOKE_ALL: {
4725
1/2
✓ Branch 0 taken 1698 times.
✗ Branch 1 not taken.
1698 if (check_access(thd, UPDATE_ACL, "mysql", nullptr, nullptr, true,
4726
4/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1691 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1696 times.
1705 true) &&
4727
3/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 5 times.
7 check_global_access(thd, CREATE_USER_ACL))
4728 2 break;
4729
4730 /* Replicate current user as grantor */
4731 1696 thd->binlog_invoker();
4732
4733 /* Conditionally writes to binlog */
4734
4/6
✓ Branch 0 taken 1696 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1663 times.
✓ Branch 3 taken 33 times.
✓ Branch 4 taken 1663 times.
✗ Branch 5 not taken.
1696 if (!(res = mysql_revoke_all(thd, lex->users_list))) my_ok(thd);
4735 1696 break;
4736 }
4737 12918 case SQLCOM_REVOKE:
4738 case SQLCOM_GRANT: {
4739 /* GRANT ... AS preliminery checks */
4740
2/2
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 12472 times.
12918 if (lex->grant_as.grant_as_used) {
4741
4/4
✓ Branch 0 taken 444 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 443 times.
446 if ((first_table || query_block->db)) {
4742
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 my_error(ER_UNSUPPORTED_USE_OF_GRANT_AS, MYF(0));
4743 3 goto error;
4744 }
4745 }
4746 /*
4747 Skip access check if we're granting a proxy
4748 */
4749
2/2
✓ Branch 0 taken 12542 times.
✓ Branch 1 taken 373 times.
12915 if (lex->type != TYPE_ENUM_PROXY) {
4750 /*
4751 If there are static grants in the GRANT statement or there are no
4752 dynamic privileges we perform check_access on GRANT_OPTION based on
4753 static global privilege level and set the DA accordingly.
4754 */
4755
4/4
✓ Branch 0 taken 2623 times.
✓ Branch 1 taken 9919 times.
✓ Branch 2 taken 390 times.
✓ Branch 3 taken 2233 times.
12542 if (lex->grant > 0 || lex->dynamic_privileges.elements == 0) {
4756 /*
4757 check_access sets DA error message based on GRANT arguments.
4758 */
4759
8/8
✓ Branch 0 taken 2145 times.
✓ Branch 1 taken 8164 times.
✓ Branch 2 taken 2145 times.
✓ Branch 3 taken 8164 times.
✓ Branch 4 taken 2145 times.
✓ Branch 5 taken 8164 times.
✓ Branch 6 taken 88 times.
✓ Branch 7 taken 10221 times.
20618 if (check_access(
4760
1/2
✓ Branch 0 taken 10309 times.
✗ Branch 1 not taken.
10309 thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
4761 first_table ? first_table->db : query_block->db,
4762 first_table ? &first_table->grant.privilege : nullptr,
4763 first_table ? &first_table->grant.m_internal : nullptr,
4764 first_table ? false : true, false)) {
4765 88 goto error;
4766 }
4767 }
4768 /*
4769 ..else we still call check_access to load internal structures, but
4770 defer checking of global dynamic GRANT_OPTION to mysql_grant. We still
4771 ignore checks if this was a grant of a proxy.
4772 */
4773 else {
4774 /*
4775 check_access will load grant.privilege and grant.m_internal with
4776 values which are used later during column privilege checking. The
4777 return value isn't interesting as we'll check for dynamic global
4778 privileges later.
4779 */
4780
7/8
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2231 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2231 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2231 times.
✓ Branch 6 taken 2233 times.
✗ Branch 7 not taken.
2233 check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
4781 first_table ? first_table->db : query_block->db,
4782 first_table ? &first_table->grant.privilege : nullptr,
4783 first_table ? &first_table->grant.m_internal : nullptr,
4784 first_table ? false : true, true);
4785 }
4786 }
4787
4788 /* Replicate current user as grantor */
4789 12827 thd->binlog_invoker();
4790
4791
3/4
✓ Branch 0 taken 12827 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11670 times.
✓ Branch 3 taken 1157 times.
12827 if (thd->security_context()->user().str) // If not replication
4792 {
4793 LEX_USER *user, *tmp_user;
4794 11670 bool first_user = true;
4795
4796
1/2
✓ Branch 0 taken 11670 times.
✗ Branch 1 not taken.
11670 List_iterator<LEX_USER> user_list(lex->users_list);
4797
2/2
✓ Branch 0 taken 12444 times.
✓ Branch 1 taken 11662 times.
24106 while ((tmp_user = user_list++)) {
4798
3/4
✓ Branch 0 taken 12444 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 12441 times.
12449 if (!(user = get_current_user(thd, tmp_user))) goto error;
4799
4/4
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 12318 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 12440 times.
12564 if (specialflag & SPECIAL_NO_RESOLVE &&
4800
3/4
✓ Branch 0 taken 123 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 122 times.
123 hostname_requires_resolving(user->host.str))
4801
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 push_warning(thd, Sql_condition::SL_WARNING,
4802 ER_WARN_HOSTNAME_WONT_WORK,
4803 ER_THD(thd, ER_WARN_HOSTNAME_WONT_WORK));
4804 // Are we trying to change a password of another user
4805
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12441 times.
12441 assert(user->host.str != nullptr);
4806
4807 /*
4808 GRANT/REVOKE PROXY has the target user as a first entry in the list.
4809 */
4810
4/4
✓ Branch 0 taken 744 times.
✓ Branch 1 taken 11697 times.
✓ Branch 2 taken 365 times.
✓ Branch 3 taken 379 times.
12441 if (lex->type == TYPE_ENUM_PROXY && first_user) {
4811 365 first_user = false;
4812
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 360 times.
365 if (acl_check_proxy_grant_access(thd, user->host.str,
4813 user->user.str,
4814
1/2
✓ Branch 0 taken 365 times.
✗ Branch 1 not taken.
365 lex->grant & GRANT_ACL))
4815 5 goto error;
4816 }
4817 }
4818 }
4819
2/2
✓ Branch 0 taken 2123 times.
✓ Branch 1 taken 10696 times.
12819 if (first_table) {
4820
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2121 times.
2123 if (lex->dynamic_privileges.elements > 0) {
4821
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (thd->lex->grant_if_exists) {
4822 push_warning_printf(thd, Sql_condition::SL_WARNING,
4823 ER_ILLEGAL_PRIVILEGE_LEVEL,
4824 ER_THD(thd, ER_ILLEGAL_PRIVILEGE_LEVEL),
4825 all_tables->table_name);
4826 } else {
4827
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 my_error(ER_ILLEGAL_PRIVILEGE_LEVEL, MYF(0),
4828 all_tables->table_name);
4829 2 goto error;
4830 }
4831 }
4832
2/2
✓ Branch 0 taken 1923 times.
✓ Branch 1 taken 198 times.
2121 if (lex->type == TYPE_ENUM_PROCEDURE ||
4833
2/2
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 1864 times.
1923 lex->type == TYPE_ENUM_FUNCTION) {
4834
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 252 times.
257 uint grants = lex->all_privileges
4835 5 ? (PROC_OP_ACLS) | (lex->grant & GRANT_ACL)
4836 : lex->grant;
4837
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 254 times.
257 if (check_grant_routine(thd, grants | GRANT_ACL, all_tables,
4838
1/2
✓ Branch 0 taken 257 times.
✗ Branch 1 not taken.
257 lex->type == TYPE_ENUM_PROCEDURE, false))
4839 3 goto error;
4840 /* Conditionally writes to binlog */
4841 508 res = mysql_routine_grant(
4842 254 thd, all_tables, lex->type == TYPE_ENUM_PROCEDURE,
4843
1/2
✓ Branch 0 taken 254 times.
✗ Branch 1 not taken.
254 lex->users_list, grants, lex->sql_command == SQLCOM_REVOKE, true);
4844
3/4
✓ Branch 0 taken 221 times.
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 221 times.
✗ Branch 3 not taken.
254 if (!res) my_ok(thd);
4845 254 } else {
4846
3/4
✓ Branch 0 taken 1864 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 1850 times.
1864 if (check_grant(thd, (lex->grant | lex->grant_tot_col | GRANT_ACL),
4847 all_tables, false, UINT_MAX, false))
4848 14 goto error;
4849 /* Conditionally writes to binlog */
4850 res =
4851 1850 mysql_table_grant(thd, all_tables, lex->users_list, lex->columns,
4852
1/2
✓ Branch 0 taken 1850 times.
✗ Branch 1 not taken.
1850 lex->grant, lex->sql_command == SQLCOM_REVOKE);
4853 }
4854 } else {
4855
1/2
✓ Branch 0 taken 10696 times.
✗ Branch 1 not taken.
10696 if (lex->columns.elements ||
4856
3/4
✓ Branch 0 taken 368 times.
✓ Branch 1 taken 10328 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 368 times.
10696 (lex->type && lex->type != TYPE_ENUM_PROXY)) {
4857 my_error(ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0));
4858 goto error;
4859 } else {
4860 /* Dynamic privileges are allowed only for global grants */
4861
4/4
✓ Branch 0 taken 2728 times.
✓ Branch 1 taken 7968 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 2720 times.
10696 if (query_block->db && lex->dynamic_privileges.elements > 0) {
4862 8 String privs;
4863 8 bool comma = false;
4864
5/8
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 21 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✓ Branch 7 taken 8 times.
21 for (const LEX_CSTRING &priv : lex->dynamic_privileges) {
4865
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
13 if (comma) privs.append(",");
4866
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 privs.append(priv.str, priv.length);
4867 13 comma = true;
4868 }
4869
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 5 times.
8 if (thd->lex->grant_if_exists) {
4870
3/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 push_warning_printf(
4871 thd, Sql_condition::SL_WARNING, ER_ILLEGAL_PRIVILEGE_LEVEL,
4872 ER_THD(thd, ER_ILLEGAL_PRIVILEGE_LEVEL), privs.c_ptr());
4873 } else {
4874
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 my_error(ER_ILLEGAL_PRIVILEGE_LEVEL, MYF(0), privs.c_ptr());
4875 5 goto error;
4876 }
4877
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 5 times.
8 }
4878 /* Conditionally writes to binlog */
4879 10679 res = mysql_grant(
4880 10691 thd, query_block->db, lex->users_list, lex->grant,
4881 10691 lex->sql_command == SQLCOM_REVOKE, lex->type == TYPE_ENUM_PROXY,
4882
1/2
✓ Branch 0 taken 10679 times.
✗ Branch 1 not taken.
10691 lex->dynamic_privileges, lex->all_privileges, &lex->grant_as);
4883 }
4884 }
4885 12783 break;
4886 }
4887 26040 case SQLCOM_RESET:
4888 /*
4889 RESET commands are never written to the binary log, so we have to
4890 initialize this variable because RESET shares the same code as FLUSH
4891 */
4892 26040 lex->no_write_to_binlog = true;
4893
3/4
✓ Branch 0 taken 3851 times.
✓ Branch 1 taken 22189 times.
✓ Branch 2 taken 3851 times.
✗ Branch 3 not taken.
26040 if ((lex->type & REFRESH_PERSIST) && (lex->option_type == OPT_PERSIST)) {
4894 Persisted_variables_cache *pv =
4895
1/2
✓ Branch 0 taken 3851 times.
✗ Branch 1 not taken.
3851 Persisted_variables_cache::get_instance();
4896
1/2
✓ Branch 0 taken 3851 times.
✗ Branch 1 not taken.
3851 if (pv)
4897
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 3824 times.
3851 if (pv->reset_persisted_variables(thd, lex->name.str,
4898
1/2
✓ Branch 0 taken 3851 times.
✗ Branch 1 not taken.
3851 lex->drop_if_exists))
4899 27 goto error;
4900
1/2
✓ Branch 0 taken 3824 times.
✗ Branch 1 not taken.
3824 my_ok(thd);
4901 3824 break;
4902 }
4903 [[fallthrough]];
4904 case SQLCOM_FLUSH: {
4905 int write_to_binlog;
4906
4907
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45345 times.
45345 if (lex->type & DUMP_MEMORY_PROFILE) {
4908
0/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
304 if (check_global_access(thd, SUPER_ACL)) goto error;
4909
3/4
✓ Branch 0 taken 45345 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 283 times.
✓ Branch 3 taken 45062 times.
45345 } else if (is_reload_request_denied(thd, lex->type))
4910 283 goto error;
4911
4912
4/4
✓ Branch 0 taken 711 times.
✓ Branch 1 taken 44351 times.
✓ Branch 2 taken 77 times.
✓ Branch 3 taken 634 times.
45062 if (first_table && lex->type & REFRESH_READ_LOCK) {
4913 #ifdef WITH_WSREP
4914
3/4
✓ Branch 0 taken 77 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 76 times.
84 if (pxc_strict_mode_lock_check(thd)) goto error;
4915 76 bool already_paused = false;
4916 #endif /* WITH_WSREP */
4917
4918 /*
4919 Do not allow FLUSH TABLES <table_list> WITH READ LOCK under an active
4920 LOCK TABLES FOR BACKUP lock.
4921 */
4922
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
76 if (thd->backup_tables_lock.abort_if_acquired()) goto error;
4923
4924 /* Check table-level privileges. */
4925
2/4
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 76 times.
76 if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables,
4926 false, UINT_MAX, false))
4927 goto error;
4928
4929 #ifdef WITH_WSREP
4930
7/10
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 59 times.
✓ Branch 4 taken 17 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 76 times.
92 if (WSREP(thd) &&
4931
2/4
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
16 !thd->global_read_lock.wsrep_pause_once(&already_paused))
4932 goto error;
4933
4934
3/4
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 69 times.
76 if (flush_tables_with_read_lock(thd, all_tables)) {
4935
6/10
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
7 if (WSREP(thd) && !already_paused)
4936
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 thd->global_read_lock.wsrep_resume_once();
4937 7 goto error;
4938 }
4939 #else
4940 if (flush_tables_with_read_lock(thd, all_tables)) goto error;
4941 #endif /* WITH_WSREP */
4942
4943
1/2
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
69 my_ok(thd);
4944 69 break;
4945
4/4
✓ Branch 0 taken 634 times.
✓ Branch 1 taken 44351 times.
✓ Branch 2 taken 337 times.
✓ Branch 3 taken 297 times.
44985 } else if (first_table && lex->type & REFRESH_FOR_EXPORT) {
4946 #ifdef WITH_WSREP
4947
3/4
✓ Branch 0 taken 337 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 336 times.
349 if (pxc_strict_mode_lock_check(thd)) goto error;
4948 336 bool already_paused = false;
4949 #endif /* WITH_WSREP */
4950 /*
4951 Do not allow FLUSH TABLES ... FOR EXPORT under an active LOCK TABLES
4952 FOR BACKUP lock.
4953 */
4954
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 336 times.
336 if (thd->backup_tables_lock.abort_if_acquired()) goto error;
4955
4956 /* Check table-level privileges. */
4957
3/4
✓ Branch 0 taken 336 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 334 times.
336 if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables,
4958 false, UINT_MAX, false))
4959 2 goto error;
4960
4961 #ifdef WITH_WSREP
4962
7/10
✓ Branch 0 taken 334 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19 times.
✓ Branch 3 taken 315 times.
✓ Branch 4 taken 19 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 18 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 334 times.
352 if (WSREP(thd) &&
4963
2/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
18 !thd->global_read_lock.wsrep_pause_once(&already_paused))
4964 goto error;
4965
4966
3/4
✓ Branch 0 taken 334 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 324 times.
334 if (flush_tables_for_export(thd, all_tables)) {
4967
7/10
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
10 if (WSREP(thd) && !already_paused)
4968
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 thd->global_read_lock.wsrep_resume_once();
4969 10 goto error;
4970 }
4971 #else
4972 if (flush_tables_for_export(thd, all_tables)) goto error;
4973 #endif /* WITH_WSREP */
4974
4975
1/2
✓ Branch 0 taken 324 times.
✗ Branch 1 not taken.
324 my_ok(thd);
4976 324 break;
4977 }
4978
4979 #ifdef WITH_WSREP
4980
4981 /* FLUSH LOGS OR FLUSH BINARY LOGS are not replicated.
4982 Check git-hash#8aa97efd935a for more details. */
4983
4984 /* REFRESH_TABLES is taken care inside handle_reload_request */
4985
2/2
✓ Branch 0 taken 7482 times.
✓ Branch 1 taken 37166 times.
44648 if (lex->type &
4986 (REFRESH_GRANT | REFRESH_HOSTS | REFRESH_STATUS |
4987 REFRESH_USER_RESOURCES | REFRESH_ERROR_LOG | REFRESH_SLOW_LOG |
4988 REFRESH_GENERAL_LOG | REFRESH_ENGINE_LOG | REFRESH_RELAY_LOG |
4989 /* Percona Server specific */
4990 REFRESH_TABLE_STATS |
4991 REFRESH_INDEX_STATS | REFRESH_USER_STATS | REFRESH_CLIENT_STATS |
4992 REFRESH_THREAD_STATS)) {
4993
12/18
✓ Branch 0 taken 7482 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 490 times.
✓ Branch 3 taken 6992 times.
✓ Branch 4 taken 490 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 476 times.
✓ Branch 7 taken 14 times.
✓ Branch 8 taken 476 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 226 times.
✓ Branch 11 taken 250 times.
✓ Branch 12 taken 226 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 226 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 7482 times.
7482 WSREP_TO_ISOLATION_BEGIN_WRTCHK(WSREP_MYSQL_DB, NULL, NULL)
4994 }
4995 #endif /* WITH_WSREP */
4996
4997 /*
4998 handle_reload_request() will tell us if we are allowed to write to the
4999 binlog or not.
5000 */
5001
3/4
✓ Branch 0 taken 44642 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 41455 times.
✓ Branch 3 taken 3187 times.
44648 if (!handle_reload_request(thd, lex->type, first_table,
5002 &write_to_binlog)) {
5003 #ifdef WITH_WSREP
5004
2/2
✓ Branch 0 taken 22208 times.
✓ Branch 1 taken 19247 times.
41455 if ((lex->type & REFRESH_TABLES) &&
5005
2/2
✓ Branch 0 taken 12337 times.
✓ Branch 1 taken 9871 times.
22208 !(lex->type & (REFRESH_FOR_EXPORT | REFRESH_READ_LOCK))) {
5006 /*
5007 This is done after handle_reload_request is because
5008 LOCK TABLES is not replicated in galera, the upgrade of which
5009 is checked in handle_reload_request.
5010 Hence, done after/if we are able to upgrade locks.
5011 */
5012
2/2
✓ Branch 0 taken 291 times.
✓ Branch 1 taken 12046 times.
12337 if (first_table) {
5013
12/18
✓ Branch 0 taken 291 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 273 times.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 15 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 12 times.
✓ Branch 11 taken 3 times.
✓ Branch 12 taken 12 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 12 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 291 times.
291 WSREP_TO_ISOLATION_BEGIN_WRTCHK(NULL, NULL, first_table);
5014 } else {
5015
13/18
✓ Branch 0 taken 12046 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9498 times.
✓ Branch 3 taken 2548 times.
✓ Branch 4 taken 464 times.
✓ Branch 5 taken 9034 times.
✓ Branch 6 taken 11 times.
✓ Branch 7 taken 453 times.
✓ Branch 8 taken 11 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 10 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 10 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 12046 times.
12046 WSREP_TO_ISOLATION_BEGIN_WRTCHK(WSREP_MYSQL_DB, NULL, NULL);
5016 }
5017 }
5018 #endif /* WITH_WSREP */
5019 /*
5020 We WANT to write and we CAN write.
5021 ! we write after unlocking the table.
5022 */
5023 /*
5024 Presumably, RESET and binlog writing doesn't require synchronization
5025 */
5026
5027
2/2
✓ Branch 0 taken 19343 times.
✓ Branch 1 taken 22112 times.
41455 if (write_to_binlog > 0) // we should write
5028 {
5029
2/2
✓ Branch 0 taken 19036 times.
✓ Branch 1 taken 307 times.
19343 if (!lex->no_write_to_binlog)
5030
1/2
✓ Branch 0 taken 19035 times.
✗ Branch 1 not taken.
19036 res = write_bin_log(thd, false, thd->query().str,
5031
2/4
✓ Branch 0 taken 19036 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19036 times.
✗ Branch 3 not taken.
19036 thd->query().length);
5032
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 22091 times.
22112 } else if (write_to_binlog < 0) {
5033 /*
5034 We should not write, but rather report error because
5035 handle_reload_request binlog interactions failed
5036 */
5037 21 res = 1;
5038 }
5039
5040
3/4
✓ Branch 0 taken 41434 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 41435 times.
✗ Branch 3 not taken.
41454 if (!res) my_ok(thd);
5041 }
5042
5043 44642 break;
5044 }
5045 2564 case SQLCOM_KILL: {
5046 2564 Item *it = lex->kill_value_list.head();
5047
5048
3/4
✓ Branch 0 taken 2564 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2563 times.
2564 if (lex->table_or_sp_used()) {
5049
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_NOT_SUPPORTED_YET, MYF(0),
5050 "Usage of subqueries or stored "
5051 "function calls as part of this statement");
5052 1 goto error;
5053 }
5054
5055
7/12
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 2516 times.
✓ Branch 2 taken 47 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 47 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2563 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 2563 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2563 times.
2563 if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1)) {
5056 my_error(ER_SET_CONSTANTS_ONLY, MYF(0));
5057 goto error;
5058 }
5059
5060
1/2
✓ Branch 0 taken 2563 times.
✗ Branch 1 not taken.
2563 my_thread_id thread_id = static_cast<my_thread_id>(it->val_int());
5061
2/4
✓ Branch 0 taken 2563 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2563 times.
2563 if (thd->is_error()) goto error;
5062
5063
1/2
✓ Branch 0 taken 2563 times.
✗ Branch 1 not taken.
2563 sql_kill(thd, thread_id, lex->type & ONLY_KILL_QUERY);
5064 2563 break;
5065 }
5066 1141 case SQLCOM_SHOW_CREATE_USER: {
5067 #ifdef WITH_WSREP
5068
10/16
✓ Branch 0 taken 1141 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1140 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✓ Branch 15 taken 1140 times.
1141 WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
5069 #endif /* WITH_WSREP */
5070
1/2
✓ Branch 0 taken 1140 times.
✗ Branch 1 not taken.
1140 LEX_USER *show_user = get_current_user(thd, lex->grant_user);
5071 1140 Security_context *sctx = thd->security_context();
5072 bool are_both_users_same =
5073
3/4
✓ Branch 0 taken 1140 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 155 times.
✓ Branch 3 taken 985 times.
1295 !strcmp(sctx->priv_user().str, show_user->user.str) &&
5074
4/6
✓ Branch 0 taken 155 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 155 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 151 times.
✓ Branch 5 taken 4 times.
155 !my_strcasecmp(system_charset_info, show_user->host.str,
5075 sctx->priv_host().str);
5076
7/8
✓ Branch 0 taken 989 times.
✓ Branch 1 taken 151 times.
✓ Branch 2 taken 989 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 981 times.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 1132 times.
✓ Branch 7 taken 8 times.
1140 if (are_both_users_same || !check_access(thd, SELECT_ACL, "mysql",
5077 nullptr, nullptr, true, false))
5078
1/2
✓ Branch 0 taken 1132 times.
✗ Branch 1 not taken.
1132 res = mysql_show_create_user(thd, show_user, are_both_users_same);
5079 1140 break;
5080 }
5081 355100 case SQLCOM_BEGIN:
5082
3/4
✓ Branch 0 taken 355256 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 355247 times.
355100 if (trans_begin(thd, lex->start_transaction_opt)) goto error;
5083
1/2
✓ Branch 0 taken 355422 times.
✗ Branch 1 not taken.
355247 my_ok(thd);
5084 355422 break;
5085 273657 case SQLCOM_COMMIT: {
5086
3/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 273647 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
273657 assert(thd->lock == nullptr ||
5087 thd->locked_tables_mode == LTM_LOCK_TABLES);
5088 273657 bool tx_chain =
5089
2/2
✓ Branch 0 taken 273653 times.
✓ Branch 1 taken 4 times.
547310 (lex->tx_chain == TVL_YES ||
5090
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 273644 times.
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
273653 (thd->variables.completion_type == 1 && lex->tx_chain != TVL_NO));
5091 273657 bool tx_release =
5092
1/2
✓ Branch 0 taken 273727 times.
✗ Branch 1 not taken.
547384 (lex->tx_release == TVL_YES ||
5093
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 273726 times.
✓ Branch 2 taken 74 times.
✗ Branch 3 not taken.
273727 (thd->variables.completion_type == 2 && lex->tx_release != TVL_NO));
5094
3/4
✓ Branch 0 taken 273783 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 104 times.
✓ Branch 3 taken 273679 times.
273657 if (trans_commit(thd)) goto error;
5095
1/2
✓ Branch 0 taken 273920 times.
✗ Branch 1 not taken.
273679 thd->mdl_context.release_transactional_locks();
5096 /* Begin transaction with the same isolation level. */
5097
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 273901 times.
273920 if (tx_chain) {
5098 #ifdef WITH_WSREP
5099 /* We need to cleanup wsrep state before starting
5100 new transaction. If 'regular' commit was issued,
5101 it would be done in caller function wsrep_dispatch_sql_command()
5102 after returning from here.
5103 But now we need to do it in between.
5104 */
5105
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 wsrep_after_statement(thd);
5106 #endif /* WITH_WSREP */
5107
2/4
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19 times.
19 if (trans_begin(thd)) goto error;
5108 } else {
5109 /* Reset the isolation level and access mode if no chaining
5110 * transaction.*/
5111
1/2
✓ Branch 0 taken 273729 times.
✗ Branch 1 not taken.
273901 trans_reset_one_shot_chistics(thd);
5112 }
5113 /* Disconnect the current client connection. */
5114
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 273744 times.
273748 if (tx_release) thd->killed = THD::KILL_CONNECTION;
5115
1/2
✓ Branch 0 taken 273878 times.
✗ Branch 1 not taken.
273748 my_ok(thd);
5116 273878 break;
5117 }
5118 10716 case SQLCOM_ROLLBACK: {
5119
3/4
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 10673 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 43 times.
10716 assert(thd->lock == nullptr ||
5120 thd->locked_tables_mode == LTM_LOCK_TABLES);
5121 10716 bool tx_chain =
5122
2/2
✓ Branch 0 taken 10712 times.
✓ Branch 1 taken 4 times.
21428 (lex->tx_chain == TVL_YES ||
5123
4/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 10709 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
10712 (thd->variables.completion_type == 1 && lex->tx_chain != TVL_NO));
5124 10716 bool tx_release =
5125
2/2
✓ Branch 0 taken 10714 times.
✓ Branch 1 taken 2 times.
21430 (lex->tx_release == TVL_YES ||
5126
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 10713 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
10714 (thd->variables.completion_type == 2 && lex->tx_release != TVL_NO));
5127
2/4
✓ Branch 0 taken 10704 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10704 times.
10716 if (trans_rollback(thd)) goto error;
5128
1/2
✓ Branch 0 taken 10704 times.
✗ Branch 1 not taken.
10704 thd->mdl_context.release_transactional_locks();
5129 /* Begin transaction with the same isolation level. */
5130
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 10698 times.
10704 if (tx_chain) {
5131 #ifdef WITH_WSREP
5132 /* We need to cleanup wsrep state before starting
5133 new transaction. If 'regular' rollback was issued,
5134 it would be done in caller function wsrep_dispatch_sql_command()
5135 after returning from here.
5136 But now we need to do it in between.
5137 */
5138
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 wsrep_after_statement(thd);
5139 #endif /* WITH_WSREP */
5140
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 if (trans_begin(thd)) goto error;
5141 } else {
5142 /* Reset the isolation level and access mode if no chaining
5143 * transaction.*/
5144
1/2
✓ Branch 0 taken 10698 times.
✗ Branch 1 not taken.
10698 trans_reset_one_shot_chistics(thd);
5145 }
5146 /* Disconnect the current client connection. */
5147
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 10701 times.
10704 if (tx_release) thd->killed = THD::KILL_CONNECTION;
5148
1/2
✓ Branch 0 taken 10704 times.
✗ Branch 1 not taken.
10704 my_ok(thd);
5149 10704 break;
5150 }
5151 38 case SQLCOM_RELEASE_SAVEPOINT:
5152
3/4
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 34 times.
38 if (trans_release_savepoint(thd, lex->ident)) goto error;
5153
1/2
✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
34 my_ok(thd);
5154 34 break;
5155 4286 case SQLCOM_ROLLBACK_TO_SAVEPOINT:
5156
3/4
✓ Branch 0 taken 4286 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 4265 times.
4286 if (trans_rollback_to_savepoint(thd, lex->ident)) goto error;
5157
1/2
✓ Branch 0 taken 4265 times.
✗ Branch 1 not taken.
4265 my_ok(thd);
5158 4265 break;
5159 8288 case SQLCOM_SAVEPOINT:
5160
3/4
✓ Branch 0 taken 8287 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 8283 times.
8288 if (trans_savepoint(thd, lex->ident)) goto error;
5161
1/2
✓ Branch 0 taken 8285 times.
✗ Branch 1 not taken.
8283 my_ok(thd);
5162 8285 break;
5163 36017 case SQLCOM_CREATE_PROCEDURE:
5164 case SQLCOM_CREATE_SPFUNCTION: {
5165 uint namelen;
5166 char *name;
5167
5168
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36017 times.
36017 assert(lex->sphead != nullptr);
5169
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36017 times.
36017 assert(lex->sphead->m_db.str); /* Must be initialized in the parser */
5170 /*
5171 Verify that the database name is allowed, optionally
5172 lowercase it.
5173 */
5174
2/4
✓ Branch 0 taken 36017 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 36017 times.
36017 if (check_and_convert_db_name(&lex->sphead->m_db, false) !=
5175 Ident_name_check::OK)
5176 26 goto error;
5177
5178
3/4
✓ Branch 0 taken 36017 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 35996 times.
36017 if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str, nullptr,
5179 nullptr, false, false))
5180 21 goto error;
5181
5182 35996 name = lex->sphead->name(&namelen);
5183
2/2
✓ Branch 0 taken 18665 times.
✓ Branch 1 taken 17331 times.
35996 if (lex->sphead->m_type == enum_sp_type::FUNCTION) {
5184
1/2
✓ Branch 0 taken 18665 times.
✗ Branch 1 not taken.
18665 udf_func *udf = find_udf(name, namelen);
5185 /*
5186 Issue a warning if there is an existing loadable function with the
5187 same name.
5188 */
5189
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 18663 times.
18665 if (udf) {
5190
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 push_warning_printf(thd, Sql_condition::SL_NOTE,
5191 ER_WARN_SF_UDF_NAME_COLLISION,
5192 ER_THD(thd, ER_WARN_SF_UDF_NAME_COLLISION), name);
5193 }
5194 }
5195
5196
3/4
✓ Branch 0 taken 35996 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 35991 times.
35996 if (sp_process_definer(thd)) goto error;
5197
5198 /*
5199 Record the CURRENT_USER in binlog. The CURRENT_USER is used on slave to
5200 grant default privileges when sp_automatic_privileges variable is set.
5201 */
5202 35991 thd->binlog_invoker();
5203
5204 #ifdef WITH_WSREP
5205
9/14
✓ Branch 0 taken 35991 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9563 times.
✓ Branch 3 taken 26428 times.
✓ Branch 4 taken 99 times.
✓ Branch 5 taken 9464 times.
✓ Branch 6 taken 99 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 99 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 99 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 35991 times.
35991 WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
5206 #endif /* WITH_WSREP */
5207
5208 35991 bool sp_already_exists = false;
5209
2/2
✓ Branch 0 taken 35910 times.
✓ Branch 1 taken 69 times.
35979 if (!(res = sp_create_routine(
5210 35991 thd, lex->sphead, thd->lex->definer,
5211
1/2
✓ Branch 0 taken 35979 times.
✗ Branch 1 not taken.
35991 thd->lex->create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS,
5212 sp_already_exists))) {
5213
2/2
✓ Branch 0 taken 35902 times.
✓ Branch 1 taken 8 times.
35910 if (!sp_already_exists) {
5214 /* only add privileges if really necessary */
5215
5216
1/2
✓ Branch 0 taken 35902 times.
✗ Branch 1 not taken.
35902 Security_context security_context;
5217 35902 bool restore_backup_context = false;
5218 35902 Security_context *backup = nullptr;
5219 /*
5220 We're going to issue an implicit GRANT statement so we close all
5221 open tables. We have to keep metadata locks as this ensures that
5222 this statement is atomic against concurrent FLUSH TABLES WITH READ
5223 LOCK. Deadlocks which can arise due to fact that this implicit
5224 statement takes metadata locks should be detected by a deadlock
5225 detector in MDL subsystem and reported as errors.
5226
5227 No need to commit/rollback statement transaction, it's not started.
5228
5229 TODO: Long-term we should either ensure that implicit GRANT
5230 statement is written into binary log as a separate statement or make
5231 both creation of routine and implicit GRANT parts of one fully
5232 atomic statement.
5233 */
5234
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35902 times.
35902 assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT));
5235
1/2
✓ Branch 0 taken 35902 times.
✗ Branch 1 not taken.
35902 close_thread_tables(thd);
5236 /*
5237 Check if invoker exists on slave, then use invoker privilege to
5238 insert routine privileges to mysql.procs_priv. If invoker is not
5239 available then consider using definer.
5240
5241 Check if the definer exists on slave,
5242 then use definer privilege to insert routine privileges to
5243 mysql.procs_priv.
5244
5245 For current user of SQL thread has GLOBAL_ACL privilege,
5246 which doesn't any check routine privileges,
5247 so no routine privilege record will insert into mysql.procs_priv.
5248 */
5249
5250
2/2
✓ Branch 0 taken 1780 times.
✓ Branch 1 taken 34122 times.
35902 if (thd->slave_thread) {
5251 LEX_CSTRING current_user;
5252 LEX_CSTRING current_host;
5253
2/2
✓ Branch 0 taken 1771 times.
✓ Branch 1 taken 9 times.
1780 if (thd->has_invoker()) {
5254 1771 current_host = thd->get_invoker_host();
5255 1771 current_user = thd->get_invoker_user();
5256 } else {
5257 9 current_host = lex->definer->host;
5258 9 current_user = lex->definer->user;
5259 }
5260
3/4
✓ Branch 0 taken 1780 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1777 times.
✓ Branch 3 taken 3 times.
1780 if (is_acl_user(thd, current_host.str, current_user.str)) {
5261 1777 security_context.change_security_context(
5262
1/2
✓ Branch 0 taken 1777 times.
✗ Branch 1 not taken.
1777 thd, current_user, current_host, thd->lex->sphead->m_db.str,
5263 &backup);
5264 1777 restore_backup_context = true;
5265 }
5266 }
5267
5268
6/6
✓ Branch 0 taken 35169 times.
✓ Branch 1 taken 733 times.
✓ Branch 2 taken 16320 times.
✓ Branch 3 taken 18849 times.
✓ Branch 4 taken 103 times.
✓ Branch 5 taken 35799 times.
52222 if (sp_automatic_privileges && !opt_noacl &&
5269
2/2
✓ Branch 0 taken 103 times.
✓ Branch 1 taken 16217 times.
16320 check_routine_access(
5270 16320 thd, DEFAULT_CREATE_PROC_ACLS, lex->sphead->m_db.str, name,
5271
1/2
✓ Branch 0 taken 16320 times.
✗ Branch 1 not taken.
16320 lex->sql_command == SQLCOM_CREATE_PROCEDURE, true)) {
5272
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 103 times.
103 if (sp_grant_privileges(
5273 103 thd, lex->sphead->m_db.str, name,
5274
1/2
✓ Branch 0 taken 103 times.
✗ Branch 1 not taken.
103 lex->sql_command == SQLCOM_CREATE_PROCEDURE))
5275 push_warning(thd, Sql_condition::SL_WARNING,
5276 ER_PROC_AUTO_GRANT_FAIL,
5277 ER_THD(thd, ER_PROC_AUTO_GRANT_FAIL));
5278
1/2
✓ Branch 0 taken 103 times.
✗ Branch 1 not taken.
103 thd->clear_error();
5279 }
5280
5281 /*
5282 Restore current user with GLOBAL_ACL privilege of SQL thread
5283 */
5284
2/2
✓ Branch 0 taken 1777 times.
✓ Branch 1 taken 34125 times.
35902 if (restore_backup_context) {
5285
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1777 times.
1777 assert(thd->slave_thread == 1);
5286
1/2
✓ Branch 0 taken 1777 times.
✗ Branch 1 not taken.
1777 thd->security_context()->restore_security_context(thd, backup);
5287 }
5288 35902 }
5289
1/2
✓ Branch 0 taken 35910 times.
✗ Branch 1 not taken.
35910 my_ok(thd);
5290 }
5291 35979 break; /* break super switch */
5292 } /* end case group bracket */
5293
5294 388 case SQLCOM_ALTER_PROCEDURE:
5295 case SQLCOM_ALTER_FUNCTION: {
5296
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 382 times.
388 if (check_routine_access(thd, ALTER_PROC_ACL, lex->spname->m_db.str,
5297 388 lex->spname->m_name.str,
5298
1/2
✓ Branch 0 taken 388 times.
✗ Branch 1 not taken.
388 lex->sql_command == SQLCOM_ALTER_PROCEDURE,
5299 false))
5300 6 goto error;
5301
5302 764 enum_sp_type sp_type = (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
5303
2/2
✓ Branch 0 taken 208 times.
✓ Branch 1 taken 174 times.
382 ? enum_sp_type::PROCEDURE
5304 : enum_sp_type::FUNCTION;
5305 /*
5306 Note that if you implement the capability of ALTER FUNCTION to
5307 alter the body of the function, this command should be made to
5308 follow the restrictions that log-bin-trust-function-creators=0
5309 already puts on CREATE FUNCTION.
5310 */
5311
5312 #ifdef WITH_WSREP
5313 // to isolation is now done as part of sp_update_routine as it does
5314 // additional ACL based check that ensures the fact that if the
5315 // definer has SUPER PRIVILIGES then DROP/ALTER should have same too.
5316 // WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
5317 // WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
5318 #endif /* WITH_WSREP */
5319
5320 /* Conditionally writes to binlog */
5321
1/2
✓ Branch 0 taken 370 times.
✗ Branch 1 not taken.
382 res = sp_update_routine(thd, sp_type, lex->spname, &lex->sp_chistics);
5322
6/6
✓ Branch 0 taken 330 times.
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 324 times.
✓ Branch 4 taken 46 times.
✓ Branch 5 taken 324 times.
370 if (res || thd->killed) goto error;
5323
5324
1/2
✓ Branch 0 taken 324 times.
✗ Branch 1 not taken.
324 my_ok(thd);
5325 324 break;
5326 }
5327 37874 case SQLCOM_DROP_PROCEDURE:
5328 case SQLCOM_DROP_FUNCTION: {
5329
2/2
✓ Branch 0 taken 18374 times.
✓ Branch 1 taken 19500 times.
37874 if (lex->sql_command == SQLCOM_DROP_FUNCTION &&
5330
2/2
✓ Branch 0 taken 16913 times.
✓ Branch 1 taken 1461 times.
18374 !lex->spname->m_explicit_name) {
5331 /* DROP FUNCTION <non qualified name> */
5332 udf_func *udf =
5333
1/2
✓ Branch 0 taken 16913 times.
✗ Branch 1 not taken.
16913 find_udf(lex->spname->m_name.str, lex->spname->m_name.length);
5334
2/2
✓ Branch 0 taken 196 times.
✓ Branch 1 taken 16717 times.
16913 if (udf) {
5335
2/4
✓ Branch 0 taken 196 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 196 times.
196 if (check_access(thd, DELETE_ACL, "mysql", nullptr, nullptr, true,
5336 false))
5337 goto error;
5338
5339 #ifdef WITH_WSREP
5340
8/14
✓ Branch 0 taken 196 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 194 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 196 times.
196 WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
5341 #endif /* WITH_WSREP */
5342
5343
3/4
✓ Branch 0 taken 190 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 184 times.
✓ Branch 3 taken 6 times.
196 if (!(res = mysql_drop_function(thd, &lex->spname->m_name))) {
5344
1/2
✓ Branch 0 taken 184 times.
✗ Branch 1 not taken.
184 my_ok(thd);
5345 184 break;
5346 }
5347 6 my_error(ER_SP_DROP_FAILED, MYF(0), "FUNCTION (UDF)",
5348
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 lex->spname->m_name.str);
5349 6 goto error;
5350 }
5351
5352
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16715 times.
16717 if (lex->spname->m_db.str == nullptr) {
5353
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (lex->drop_if_exists) {
5354
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 push_warning_printf(thd, Sql_condition::SL_NOTE,
5355 ER_SP_DOES_NOT_EXIST,
5356 ER_THD(thd, ER_SP_DOES_NOT_EXIST),
5357
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 "FUNCTION (UDF)", lex->spname->m_name.str);
5358 1 res = false;
5359
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_ok(thd);
5360 1 break;
5361 }
5362 1 my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION (UDF)",
5363
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 lex->spname->m_name.str);
5364 1 goto error;
5365 }
5366 /* Fall thought to test for a stored function */
5367 }
5368
5369 37676 const char *db = lex->spname->m_db.str;
5370 37676 char *name = lex->spname->m_name.str;
5371
5372
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 37656 times.
37676 if (check_routine_access(thd, ALTER_PROC_ACL, db, name,
5373
1/2
✓ Branch 0 taken 37676 times.
✗ Branch 1 not taken.
37676 lex->sql_command == SQLCOM_DROP_PROCEDURE,
5374 false))
5375 20 goto error;
5376
5377 #ifdef WITH_WSREP
5378 // to isolation is now done as part of sp_drop_routine as it does
5379 // additional ACL based check that ensures the fact that if the
5380 // definer has SUPER PRIVILIGES then DROP/ATLER should have same too.
5381 // WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
5382 #endif /* WITH_WSREP */
5383
5384 75312 enum_sp_type sp_type = (lex->sql_command == SQLCOM_DROP_PROCEDURE)
5385
2/2
✓ Branch 0 taken 19486 times.
✓ Branch 1 taken 18170 times.
37656 ? enum_sp_type::PROCEDURE
5386 : enum_sp_type::FUNCTION;
5387
5388 /* Conditionally writes to binlog */
5389 enum_sp_return_code sp_result =
5390
1/2
✓ Branch 0 taken 37644 times.
✗ Branch 1 not taken.
37656 sp_drop_routine(thd, sp_type, lex->spname);
5391
5392 /*
5393 We're going to issue an implicit REVOKE statement so we close all
5394 open tables. We have to keep metadata locks as this ensures that
5395 this statement is atomic against concurrent FLUSH TABLES WITH READ
5396 LOCK. Deadlocks which can arise due to fact that this implicit
5397 statement takes metadata locks should be detected by a deadlock
5398 detector in MDL subsystem and reported as errors.
5399
5400 No need to commit/rollback statement transaction, it's not started.
5401
5402 TODO: Long-term we should either ensure that implicit REVOKE statement
5403 is written into binary log as a separate statement or make both
5404 dropping of routine and implicit REVOKE parts of one fully atomic
5405 statement.
5406 */
5407
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37644 times.
37644 assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT));
5408
1/2
✓ Branch 0 taken 37644 times.
✗ Branch 1 not taken.
37644 close_thread_tables(thd);
5409
5410 #ifdef WITH_WSREP
5411 // sp_drop_routine() returns SP_INTERNAL_ERROR in case of system user
5412 // privileges check failure. In such a case we don't want to proceed with
5413 // sp_revoke_privileges which will fail anyway.
5414
2/2
✓ Branch 0 taken 37637 times.
✓ Branch 1 taken 7 times.
37644 if (sp_result != SP_INTERNAL_ERROR) {
5415 #endif
5416
2/2
✓ Branch 0 taken 21800 times.
✓ Branch 1 taken 732 times.
22532 if (sp_result != SP_DOES_NOT_EXISTS && sp_automatic_privileges &&
5417
6/6
✓ Branch 0 taken 22532 times.
✓ Branch 1 taken 15105 times.
✓ Branch 2 taken 13165 times.
✓ Branch 3 taken 8635 times.
✓ Branch 4 taken 36 times.
✓ Branch 5 taken 37601 times.
73334 !opt_noacl &&
5418
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 13129 times.
13165 sp_revoke_privileges(thd, db, name,
5419
1/2
✓ Branch 0 taken 13165 times.
✗ Branch 1 not taken.
13165 lex->sql_command == SQLCOM_DROP_PROCEDURE)) {
5420
2/4
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
36 push_warning(thd, Sql_condition::SL_WARNING, ER_PROC_AUTO_REVOKE_FAIL,
5421 ER_THD(thd, ER_PROC_AUTO_REVOKE_FAIL));
5422 /* If this happens, an error should have been reported. */
5423 36 goto error;
5424 }
5425 #ifdef WITH_WSREP
5426 }
5427 #endif
5428
5429 37608 res = sp_result;
5430
3/3
✓ Branch 0 taken 22494 times.
✓ Branch 1 taken 15105 times.
✓ Branch 2 taken 9 times.
37608 switch (sp_result) {
5431 22494 case SP_OK:
5432
1/2
✓ Branch 0 taken 22494 times.
✗ Branch 1 not taken.
22494 my_ok(thd);
5433 22494 break;
5434 15105 case SP_DOES_NOT_EXISTS:
5435
2/2
✓ Branch 0 taken 15072 times.
✓ Branch 1 taken 33 times.
15105 if (lex->drop_if_exists) {
5436 res =
5437
3/6
✓ Branch 0 taken 15072 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15072 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15072 times.
✗ Branch 5 not taken.
15072 write_bin_log(thd, true, thd->query().str, thd->query().length);
5438
2/4
✓ Branch 0 taken 15072 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15072 times.
✗ Branch 3 not taken.
15072 push_warning_printf(thd, Sql_condition::SL_NOTE,
5439 ER_SP_DOES_NOT_EXIST,
5440 ER_THD(thd, ER_SP_DOES_NOT_EXIST),
5441
5/8
✓ Branch 0 taken 15072 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15072 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15072 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5286 times.
✓ Branch 7 taken 9786 times.
15072 SP_COM_STRING(lex), lex->spname->m_qname.str);
5442
2/4
✓ Branch 0 taken 15072 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15072 times.
✗ Branch 3 not taken.
15072 if (!res) my_ok(thd);
5443 15072 break;
5444 }
5445
5/8
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 33 times.
✗ Branch 7 not taken.
33 my_error(ER_SP_DOES_NOT_EXIST, MYF(0), SP_COM_STRING(lex),
5446
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 lex->spname->m_qname.str);
5447 33 goto error;
5448 9 default:
5449
5/8
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
9 my_error(ER_SP_DROP_FAILED, MYF(0), SP_COM_STRING(lex),
5450
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 lex->spname->m_qname.str);
5451 9 goto error;
5452 }
5453 37566 break;
5454 }
5455 67480 case SQLCOM_CREATE_VIEW: {
5456 /*
5457 Note: SQLCOM_CREATE_VIEW also handles 'ALTER VIEW' commands
5458 as specified through the thd->lex->create_view_mode flag.
5459 */
5460
1/2
✓ Branch 0 taken 67468 times.
✗ Branch 1 not taken.
67480 res = mysql_create_view(thd, first_table, thd->lex->create_view_mode);
5461 67468 break;
5462 }
5463 4822 case SQLCOM_DROP_VIEW: {
5464
3/4
✓ Branch 0 taken 4822 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 4820 times.
4822 if (check_table_access(thd, DROP_ACL, all_tables, false, UINT_MAX, false))
5465 2 goto error;
5466
5467 #ifdef WITH_WSREP
5468 // check is now done as part od drop view post definer SUPER PRIVILIGES
5469 // check. WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
5470 #endif /* WITH_WSREP */
5471
5472 /* Conditionally writes to binlog. */
5473
1/2
✓ Branch 0 taken 4814 times.
✗ Branch 1 not taken.
4820 res = mysql_drop_view(thd, first_table);
5474 4814 break;
5475 }
5476 23839 case SQLCOM_CREATE_TRIGGER:
5477 case SQLCOM_DROP_TRIGGER: {
5478 /* Conditionally writes to binlog. */
5479
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23839 times.
23839 assert(lex->m_sql_cmd != nullptr);
5480 23839 static_cast<Sql_cmd_ddl_trigger_common *>(lex->m_sql_cmd)
5481 23839 ->set_table(all_tables);
5482
5483
1/2
✓ Branch 0 taken 23827 times.
✗ Branch 1 not taken.
23839 res = lex->m_sql_cmd->execute(thd);
5484 23827 break;
5485 }
5486 3702 case SQLCOM_BINLOG_BASE64_EVENT: {
5487
1/2
✓ Branch 0 taken 3702 times.
✗ Branch 1 not taken.
3702 mysql_client_binlog_statement(thd);
5488 3702 break;
5489 }
5490 158956 case SQLCOM_ANALYZE:
5491 case SQLCOM_CHECK:
5492 case SQLCOM_OPTIMIZE:
5493 case SQLCOM_REPAIR:
5494 case SQLCOM_TRUNCATE:
5495 case SQLCOM_ALTER_TABLE:
5496 case SQLCOM_HA_OPEN:
5497 case SQLCOM_HA_READ:
5498 case SQLCOM_HA_CLOSE:
5499
2/4
✓ Branch 0 taken 158956 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 158956 times.
✗ Branch 3 not taken.
158956 assert(first_table == all_tables && first_table != nullptr);
5500 [[fallthrough]];
5501 case SQLCOM_CREATE_SERVER:
5502 case SQLCOM_CREATE_RESOURCE_GROUP:
5503 case SQLCOM_ALTER_SERVER:
5504 case SQLCOM_ALTER_RESOURCE_GROUP:
5505 case SQLCOM_DROP_RESOURCE_GROUP:
5506 case SQLCOM_DROP_SERVER:
5507 case SQLCOM_SET_RESOURCE_GROUP:
5508 case SQLCOM_SIGNAL:
5509 case SQLCOM_RESIGNAL:
5510 case SQLCOM_GET_DIAGNOSTICS:
5511 case SQLCOM_CHANGE_REPLICATION_FILTER:
5512 case SQLCOM_XA_START:
5513 case SQLCOM_XA_END:
5514 case SQLCOM_XA_PREPARE:
5515 case SQLCOM_XA_COMMIT:
5516 case SQLCOM_XA_ROLLBACK:
5517 case SQLCOM_XA_RECOVER:
5518 case SQLCOM_INSTALL_PLUGIN:
5519 case SQLCOM_UNINSTALL_PLUGIN:
5520 case SQLCOM_INSTALL_COMPONENT:
5521 case SQLCOM_UNINSTALL_COMPONENT:
5522 case SQLCOM_SHUTDOWN:
5523 case SQLCOM_ALTER_INSTANCE:
5524 case SQLCOM_SELECT:
5525 case SQLCOM_DO:
5526 case SQLCOM_CALL:
5527 case SQLCOM_CREATE_ROLE:
5528 case SQLCOM_DROP_ROLE:
5529 case SQLCOM_SET_ROLE:
5530 case SQLCOM_GRANT_ROLE:
5531 case SQLCOM_REVOKE_ROLE:
5532 case SQLCOM_ALTER_USER_DEFAULT_ROLE:
5533 case SQLCOM_SHOW_BINLOG_EVENTS:
5534 case SQLCOM_SHOW_BINLOGS:
5535 case SQLCOM_SHOW_CHARSETS:
5536 case SQLCOM_SHOW_COLLATIONS:
5537 case SQLCOM_SHOW_CREATE_DB:
5538 case SQLCOM_SHOW_CREATE_EVENT:
5539 case SQLCOM_SHOW_CREATE_FUNC:
5540 case SQLCOM_SHOW_CREATE_PROC:
5541 case SQLCOM_SHOW_CREATE:
5542 case SQLCOM_SHOW_CREATE_TRIGGER:
5543 // case SQLCOM_SHOW_CREATE_USER:
5544 case SQLCOM_SHOW_DATABASES:
5545 case SQLCOM_SHOW_ENGINE_LOGS:
5546 case SQLCOM_SHOW_ENGINE_MUTEX:
5547 case SQLCOM_SHOW_ENGINE_STATUS:
5548 case SQLCOM_SHOW_ERRORS:
5549 case SQLCOM_SHOW_EVENTS:
5550 case SQLCOM_SHOW_FIELDS:
5551 case SQLCOM_SHOW_FUNC_CODE:
5552 case SQLCOM_SHOW_GRANTS:
5553 case SQLCOM_SHOW_KEYS:
5554 case SQLCOM_SHOW_MASTER_STAT:
5555 case SQLCOM_SHOW_OPEN_TABLES:
5556 case SQLCOM_SHOW_PLUGINS:
5557 case SQLCOM_SHOW_PRIVILEGES:
5558 case SQLCOM_SHOW_PROC_CODE:
5559 case SQLCOM_SHOW_PROCESSLIST:
5560 case SQLCOM_SHOW_PROFILE:
5561 case SQLCOM_SHOW_PROFILES:
5562 case SQLCOM_SHOW_RELAYLOG_EVENTS:
5563 case SQLCOM_SHOW_SLAVE_HOSTS:
5564 case SQLCOM_SHOW_SLAVE_STAT:
5565 case SQLCOM_SHOW_STATUS:
5566 case SQLCOM_SHOW_STORAGE_ENGINES:
5567 case SQLCOM_SHOW_TABLE_STATUS:
5568 case SQLCOM_SHOW_TABLES:
5569 case SQLCOM_SHOW_TRIGGERS:
5570 case SQLCOM_SHOW_STATUS_PROC:
5571 case SQLCOM_SHOW_STATUS_FUNC:
5572 case SQLCOM_SHOW_VARIABLES:
5573 case SQLCOM_SHOW_WARNS:
5574 case SQLCOM_SHOW_USER_STATS:
5575 case SQLCOM_SHOW_TABLE_STATS:
5576 case SQLCOM_SHOW_INDEX_STATS:
5577 case SQLCOM_SHOW_CLIENT_STATS:
5578 case SQLCOM_SHOW_THREAD_STATS:
5579 case SQLCOM_CLONE:
5580 case SQLCOM_LOCK_INSTANCE:
5581 case SQLCOM_UNLOCK_INSTANCE:
5582 case SQLCOM_ALTER_TABLESPACE:
5583 case SQLCOM_EXPLAIN_OTHER:
5584 case SQLCOM_RESTART_SERVER:
5585 case SQLCOM_CREATE_SRS:
5586 case SQLCOM_DROP_SRS: {
5587 #ifdef WITH_WSREP
5588
2/2
✓ Branch 0 taken 8396030 times.
✓ Branch 1 taken 1063931 times.
9459961 if (lex->sql_command == SQLCOM_SELECT)
5589
14/16
✓ Branch 0 taken 8396032 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 120272 times.
✓ Branch 3 taken 8275760 times.
✓ Branch 4 taken 118452 times.
✓ Branch 5 taken 1820 times.
✓ Branch 6 taken 116227 times.
✓ Branch 7 taken 2225 times.
✓ Branch 8 taken 116226 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 116226 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 294 times.
✓ Branch 13 taken 115932 times.
✓ Branch 14 taken 294 times.
✓ Branch 15 taken 8395736 times.
8396030 WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_READ)
5590
5591 static std::vector<enum_sql_command> wait_before_show_commands = {
5592 SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_FIELDS,
5593 SQLCOM_SHOW_KEYS, SQLCOM_SHOW_TABLES,
5594 SQLCOM_SHOW_CREATE_PROC, SQLCOM_SHOW_CREATE_FUNC,
5595 SQLCOM_SHOW_PROC_CODE, SQLCOM_SHOW_FUNC_CODE,
5596 SQLCOM_SHOW_CREATE_TRIGGER, SQLCOM_SHOW_STATUS,
5597 SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_BINLOGS,
5598 SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CREATE_DB,
5599 SQLCOM_SHOW_CREATE_EVENT, SQLCOM_SHOW_STATUS_PROC,
5600 SQLCOM_SHOW_STATUS_FUNC, SQLCOM_SHOW_DATABASES,
5601 SQLCOM_SHOW_TRIGGERS, SQLCOM_SHOW_TABLE_STATUS,
5602 SQLCOM_SHOW_OPEN_TABLES, SQLCOM_SHOW_PLUGINS,
5603 SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_CHARSETS,
5604 SQLCOM_SHOW_COLLATIONS, SQLCOM_SHOW_STORAGE_ENGINES,
5605 SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_USER_STATS,
5606 SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS,
5607
4/8
✓ Branch 0 taken 9394 times.
✓ Branch 1 taken 9450273 times.
✓ Branch 2 taken 9394 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9394 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
9459667 SQLCOM_SHOW_CLIENT_STATS, SQLCOM_SHOW_THREAD_STATS};
5608
1/2
✓ Branch 0 taken 9457779 times.
✗ Branch 1 not taken.
9457742 if (std::find(std::begin(wait_before_show_commands),
5609 std::end(wait_before_show_commands),
5610
2/2
✓ Branch 0 taken 281984 times.
✓ Branch 1 taken 9175789 times.
18917446 lex->sql_command) != std::end(wait_before_show_commands)) {
5611
12/16
✓ Branch 0 taken 281984 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15672 times.
✓ Branch 3 taken 266312 times.
✓ Branch 4 taken 15672 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15651 times.
✓ Branch 7 taken 21 times.
✓ Branch 8 taken 15651 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 15651 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 225 times.
✓ Branch 13 taken 15426 times.
✓ Branch 14 taken 225 times.
✓ Branch 15 taken 281759 times.
281984 WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
5612 }
5613
5614
2/2
✓ Branch 0 taken 9456958 times.
✓ Branch 1 taken 590 times.
9457548 if (lex->sql_command == SQLCOM_CREATE_SRS ||
5615
2/2
✓ Branch 0 taken 9456761 times.
✓ Branch 1 taken 197 times.
9456958 lex->sql_command == SQLCOM_DROP_SRS ||
5616
2/2
✓ Branch 0 taken 9456264 times.
✓ Branch 1 taken 497 times.
9456761 lex->sql_command == SQLCOM_INSTALL_COMPONENT ||
5617
2/2
✓ Branch 0 taken 431 times.
✓ Branch 1 taken 9455833 times.
9456264 lex->sql_command == SQLCOM_UNINSTALL_COMPONENT) {
5618
8/14
✓ Branch 0 taken 1715 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 1709 times.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 6 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1715 times.
1715 WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
5619 }
5620
5621
2/2
✓ Branch 0 taken 9456549 times.
✓ Branch 1 taken 999 times.
9457548 if (lex->sql_command == SQLCOM_XA_START ||
5622
2/2
✓ Branch 0 taken 9455680 times.
✓ Branch 1 taken 869 times.
9456549 lex->sql_command == SQLCOM_XA_END ||
5623
2/2
✓ Branch 0 taken 9455294 times.
✓ Branch 1 taken 386 times.
9455680 lex->sql_command == SQLCOM_XA_PREPARE ||
5624
2/2
✓ Branch 0 taken 9454678 times.
✓ Branch 1 taken 616 times.
9455294 lex->sql_command == SQLCOM_XA_COMMIT ||
5625
2/2
✓ Branch 0 taken 9454423 times.
✓ Branch 1 taken 255 times.
9454678 lex->sql_command == SQLCOM_XA_ROLLBACK ||
5626
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 9454170 times.
9454423 lex->sql_command == SQLCOM_XA_RECOVER) {
5627
6/8
✓ Branch 0 taken 3295 times.
✓ Branch 1 taken 83 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 3287 times.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
3378 if (WSREP(thd)) {
5628
1/26
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
8 WSREP_DEBUG("XA command attempted: %d %s, thd: %u", lex->sql_command,
5629 thd->query().str, thd->thread_id());
5630
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 my_error(ER_NOT_SUPPORTED_YET, MYF(0),
5631 "XA with wsrep replication plugin");
5632 8 break;
5633 }
5634 }
5635 #endif /* WITH_WSREP */
5636
5637
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9457540 times.
9457540 assert(lex->m_sql_cmd != nullptr);
5638
5639
1/2
✓ Branch 0 taken 9456721 times.
✗ Branch 1 not taken.
9457540 res = lex->m_sql_cmd->execute(thd);
5640
5641 9456721 break;
5642 }
5643 2543 case SQLCOM_ALTER_USER: {
5644 LEX_USER *user, *tmp_user;
5645 2543 bool changing_own_password = false;
5646 2543 Security_context *sctx = thd->security_context();
5647
1/2
✓ Branch 0 taken 2543 times.
✗ Branch 1 not taken.
2543 bool own_password_expired = sctx->password_expired();
5648 2543 bool check_permission = true;
5649 /* track if it is ALTER USER registration step */
5650 2543 bool finish_reg = false;
5651 2543 bool init_reg = false;
5652 2543 bool unregister = false;
5653 2543 bool is_self = false;
5654
5655
1/2
✓ Branch 0 taken 2543 times.
✗ Branch 1 not taken.
2543 List_iterator<LEX_USER> user_list(lex->users_list);
5656
2/2
✓ Branch 0 taken 2934 times.
✓ Branch 1 taken 2498 times.
5432 while ((tmp_user = user_list++)) {
5657 LEX_MFA *tmp_lex_mfa;
5658
1/2
✓ Branch 0 taken 2934 times.
✗ Branch 1 not taken.
2934 List_iterator<LEX_MFA> mfa_list_it(tmp_user->mfa_list);
5659
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2934 times.
2934 while ((tmp_lex_mfa = mfa_list_it++)) {
5660 finish_reg |= tmp_lex_mfa->finish_registration;
5661 init_reg |= tmp_lex_mfa->init_registration;
5662 unregister |= tmp_lex_mfa->unregister;
5663 }
5664 2934 bool update_password_only = false;
5665 2934 bool second_password = false;
5666
5667 /* If it is an empty lex_user update it with current user */
5668
3/4
✓ Branch 0 taken 166 times.
✓ Branch 1 taken 2768 times.
✓ Branch 2 taken 166 times.
✗ Branch 3 not taken.
2934 if (!tmp_user->host.str && !tmp_user->user.str) {
5669 #ifdef WITH_WSREP
5670
5/8
✓ Branch 0 taken 166 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 162 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
166 if (WSREP(thd)) {
5671
13/28
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 4 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 4 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 4 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 4 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 4 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 4 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 4 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
4 WSREP_ERROR(
5672 "Percona XtraDB Cluster doesn't allow use of"
5673 " CURRENT_USER/USER function for USER operation"
5674 " while operating in cluster mode");
5675 char message[1024];
5676 4 sprintf(message,
5677 "Percona XtraDB Cluster doesn't allow use of"
5678 " CURRENT_USER/USER function for USER operation"
5679 " while operating in cluster mode");
5680
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 my_message(ER_UNKNOWN_ERROR, message, MYF(0));
5681 4 goto error;
5682 }
5683 #endif /* WITH_WSREP */
5684
5685 /* set user information as of the current user */
5686
2/4
✓ Branch 0 taken 162 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 162 times.
162 assert(sctx->priv_host().str);
5687
1/2
✓ Branch 0 taken 162 times.
✗ Branch 1 not taken.
162 tmp_user->host.str = sctx->priv_host().str;
5688
1/2
✓ Branch 0 taken 162 times.
✗ Branch 1 not taken.
162 tmp_user->host.length = strlen(sctx->priv_host().str);
5689
2/4
✓ Branch 0 taken 162 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 162 times.
162 assert(sctx->user().str);
5690
1/2
✓ Branch 0 taken 162 times.
✗ Branch 1 not taken.
162 tmp_user->user.str = sctx->user().str;
5691
1/2
✓ Branch 0 taken 162 times.
✗ Branch 1 not taken.
162 tmp_user->user.length = strlen(sctx->user().str);
5692 }
5693
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2930 times.
2930 if (!(user = get_current_user(thd, tmp_user))) goto error;
5694
5695 #ifdef WITH_WSREP
5696 /* When ALTER USER ... IDENTIFIED BY ... REPLACE ... is executed
5697 we need to know the current user to be able to determine REPLACE
5698 clause validity (REPLACE allowed only for the current user's password
5699 change). However ALTER USER is replicated as TOI, so before local
5700 validation/changes. On the slave side, executing thread is wsrep
5701 applier thread and we have no chance to determine if it is OK or not.
5702 Here we do pre-validation for above condition on master size.
5703 Other checks that are not dependent on current user context will be
5704 made made after replication, on slave node */
5705
8/10
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 332 times.
✓ Branch 3 taken 2598 times.
✓ Branch 4 taken 332 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 47 times.
✓ Branch 7 taken 285 times.
✓ Branch 8 taken 24 times.
✓ Branch 9 taken 23 times.
2930 if (WSREP(thd) && thd->system_thread == NON_SYSTEM_THREAD) {
5706 24 Security_context *sctx2 = thd->security_context();
5707
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 assert(sctx2);
5708
2/4
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
24 assert(sctx2->user().str);
5709
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 16 times.
24 if (user->uses_replace_clause) {
5710 // If trying to set password for other user
5711
5/6
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 3 times.
11 if (strcmp(sctx2->user().str, user->user.str) ||
5712
3/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
3 my_strcasecmp(system_charset_info, sctx2->priv_host().str,
5713 user->host.str)) {
5714
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 my_error(ER_CURRENT_PASSWORD_NOT_REQUIRED, MYF(0));
5715 5 goto error;
5716 }
5717 }
5718 }
5719 #endif /* WITH_WSREP */
5720
5721 /* copy password expire attributes to individual lex user */
5722 2925 user->alter_status = thd->lex->alter_password;
5723 /*
5724 Only self password change is non-privileged operation. To detect the
5725 same, we find :
5726 (1) If it is only password change operation
5727 (2) If this operation is on self
5728 */
5729
2/2
✓ Branch 0 taken 1198 times.
✓ Branch 1 taken 1727 times.
2925 if (user->first_factor_auth_info.uses_identified_by_clause &&
5730
2/2
✓ Branch 0 taken 1118 times.
✓ Branch 1 taken 80 times.
1198 !user->first_factor_auth_info.uses_identified_with_clause &&
5731
2/2
✓ Branch 0 taken 1088 times.
✓ Branch 1 taken 30 times.
1118 !thd->lex->mqh.specified_limits &&
5732
2/2
✓ Branch 0 taken 1082 times.
✓ Branch 1 taken 6 times.
1088 !user->alter_status.update_account_locked_column &&
5733
2/2
✓ Branch 0 taken 1081 times.
✓ Branch 1 taken 1 times.
1082 !user->alter_status.update_password_expired_column &&
5734
2/2
✓ Branch 0 taken 1075 times.
✓ Branch 1 taken 6 times.
1081 !user->alter_status.expire_after_days &&
5735
2/2
✓ Branch 0 taken 1072 times.
✓ Branch 1 taken 3 times.
1075 user->alter_status.use_default_password_lifetime &&
5736
2/2
✓ Branch 0 taken 1060 times.
✓ Branch 1 taken 12 times.
1072 (user->alter_status.update_password_require_current ==
5737 1060 Lex_acl_attrib_udyn::UNCHANGED) &&
5738
1/2
✓ Branch 0 taken 1060 times.
✗ Branch 1 not taken.
1060 !user->alter_status.update_password_history &&
5739
1/2
✓ Branch 0 taken 1060 times.
✗ Branch 1 not taken.
1060 !user->alter_status.update_password_reuse_interval &&
5740
1/2
✓ Branch 0 taken 1060 times.
✗ Branch 1 not taken.
1060 !user->alter_status.update_failed_login_attempts &&
5741
1/2
✓ Branch 0 taken 1060 times.
✗ Branch 1 not taken.
1060 !user->alter_status.update_password_lock_time &&
5742
2/2
✓ Branch 0 taken 1059 times.
✓ Branch 1 taken 1 times.
1060 (thd->lex->ssl_type == SSL_TYPE_NOT_SPECIFIED))
5743 1059 update_password_only = true;
5744
5745
4/6
✓ Branch 0 taken 2925 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2462 times.
✓ Branch 3 taken 463 times.
✓ Branch 4 taken 2462 times.
✗ Branch 5 not taken.
2925 is_self = !strcmp(sctx->user().length ? sctx->user().str : "",
5746
2/2
✓ Branch 0 taken 658 times.
✓ Branch 1 taken 2267 times.
3583 user->user.str) &&
5747
3/6
✓ Branch 0 taken 658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 658 times.
✗ Branch 5 not taken.
658 !my_strcasecmp(&my_charset_latin1, user->host.str,
5748 sctx->priv_host().str);
5749
2/4
✓ Branch 0 taken 2925 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2925 times.
2925 if (finish_reg || init_reg) {
5750 /* Registration step is allowed only for connecting users */
5751 if (!is_self) {
5752 my_error(ER_INVALID_USER_FOR_REGISTRATION, MYF(0), sctx->user().str,
5753 sctx->priv_host().str);
5754 goto error;
5755 }
5756 }
5757 /*
5758 if user executes ALTER statement to change password only
5759 for himself then skip access check - Provided preference to
5760 retain/discard current password was specified.
5761 */
5762
5763
4/4
✓ Branch 0 taken 2880 times.
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 45 times.
✓ Branch 3 taken 2835 times.
2925 if (user->discard_old_password || user->retain_current_password) {
5764 90 second_password = true;
5765 }
5766
6/8
✓ Branch 0 taken 1866 times.
✓ Branch 1 taken 1059 times.
✓ Branch 2 taken 1821 times.
✓ Branch 3 taken 45 times.
✓ Branch 4 taken 1821 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1821 times.
✗ Branch 7 not taken.
2925 if ((update_password_only || user->discard_old_password || init_reg ||
5767
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1821 times.
✓ Branch 2 taken 314 times.
✓ Branch 3 taken 790 times.
2925 finish_reg || unregister) &&
5768 is_self) {
5769 314 changing_own_password = update_password_only;
5770
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 301 times.
314 if (second_password) {
5771
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (check_access(thd, UPDATE_ACL, consts::mysql.c_str(), nullptr,
5772 24 nullptr, true, true) &&
5773
11/18
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 9 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 12 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 12 times.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
35 !sctx->check_access(CREATE_USER_ACL, consts::mysql.c_str()) &&
5774
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 !(sctx->has_global_grant(
5775 STRING_WITH_LEN("APPLICATION_PASSWORD_ADMIN"))
5776
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 .first)) {
5777 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0),
5778 "CREATE USER or APPLICATION_PASSWORD_ADMIN");
5779 goto error;
5780 }
5781 }
5782 314 continue;
5783
2/2
✓ Branch 0 taken 2230 times.
✓ Branch 1 taken 381 times.
2611 } else if (check_permission) {
5784
1/2
✓ Branch 0 taken 2230 times.
✗ Branch 1 not taken.
2230 if (check_access(thd, UPDATE_ACL, "mysql", nullptr, nullptr, true,
5785
4/4
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 2194 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 2214 times.
2266 true) &&
5786
3/4
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 20 times.
36 check_global_access(thd, CREATE_USER_ACL))
5787 16 goto error;
5788
5789 2214 check_permission = false;
5790 }
5791
5792
2/2
✓ Branch 0 taken 337 times.
✓ Branch 1 taken 2258 times.
2595 if (is_self &&
5793
2/2
✓ Branch 0 taken 317 times.
✓ Branch 1 taken 20 times.
337 (user->first_factor_auth_info.uses_identified_by_clause ||
5794
1/2
✓ Branch 0 taken 317 times.
✗ Branch 1 not taken.
317 user->first_factor_auth_info.uses_identified_with_clause ||
5795
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 317 times.
317 user->first_factor_auth_info.uses_authentication_string_clause)) {
5796 20 changing_own_password = true;
5797 20 break;
5798 }
5799
5800
2/2
✓ Branch 0 taken 743 times.
✓ Branch 1 taken 2 times.
745 if (update_password_only &&
5801
4/6
✓ Branch 0 taken 745 times.
✓ Branch 1 taken 1830 times.
✓ Branch 2 taken 745 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2575 times.
3320 likely((get_server_state() == SERVER_OPERATING)) &&
5802
2/4
✓ Branch 0 taken 743 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 743 times.
743 !strcmp(sctx->priv_user().str, "")) {
5803 my_error(ER_PASSWORD_ANONYMOUS_USER, MYF(0));
5804 goto error;
5805 }
5806 }
5807
5808
6/6
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 2482 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 33 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 2515 times.
2518 if (unlikely(own_password_expired && !changing_own_password)) {
5809
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 my_error(ER_MUST_CHANGE_PASSWORD, MYF(0));
5810 3 goto error;
5811 }
5812 /* Conditionally writes to binlog */
5813
1/2
✓ Branch 0 taken 2505 times.
✗ Branch 1 not taken.
2515 res = mysql_alter_user(thd, lex->users_list, lex->drop_if_exists);
5814 /*
5815 Iterate over list of MFA methods, check if all auth plugin methods
5816 which need registration steps have completed, then turn OFF server
5817 sandbox mode
5818 */
5819 2505 tmp_user = lex->users_list[0];
5820
5/6
✓ Branch 0 taken 2191 times.
✓ Branch 1 taken 314 times.
✓ Branch 2 taken 517 times.
✓ Branch 3 taken 1674 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 517 times.
2505 if (!res && is_self && finish_reg) {
5821 if (turn_off_sandbox_mode(thd, tmp_user)) return true;
5822 }
5823 2505 break;
5824 }
5825 default:
5826 assert(0); /* Impossible */
5827 my_ok(thd);
5828 break;
5829 }
5830 21345987 goto finish;
5831
5832 17002 error:
5833 #ifdef WITH_WSREP
5834 17002 wsrep_error_label:
5835 #endif /* WITH_WSREP */
5836 17002 res = true;
5837
5838 21362989 finish:
5839 /* Restore system variables which were changed by SET_VAR hint. */
5840
4/4
✓ Branch 0 taken 7755 times.
✓ Branch 1 taken 21355234 times.
✓ Branch 2 taken 6736 times.
✓ Branch 3 taken 1019 times.
21362989 if (lex->opt_hints_global && lex->opt_hints_global->sys_var_hint)
5841
1/2
✓ Branch 0 taken 6736 times.
✗ Branch 1 not taken.
6736 lex->opt_hints_global->sys_var_hint->restore_vars(thd);
5842
5843
1/2
✓ Branch 0 taken 21363258 times.
✗ Branch 1 not taken.
21362989 THD_STAGE_INFO(thd, stage_query_end);
5844
5845 // Check for receiving a recent kill signal
5846
2/2
✓ Branch 0 taken 1293 times.
✓ Branch 1 taken 21361914 times.
21363258 if (thd->killed) {
5847
1/2
✓ Branch 0 taken 754 times.
✗ Branch 1 not taken.
1293 thd->send_kill_message();
5848
1/2
✓ Branch 0 taken 754 times.
✗ Branch 1 not taken.
754 res = thd->is_error();
5849 }
5850
2/2
✓ Branch 0 taken 151379 times.
✓ Branch 1 taken 21211289 times.
21362668 if (res) {
5851
3/4
✓ Branch 0 taken 151381 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37720 times.
✓ Branch 3 taken 4810 times.
193909 if (thd->get_reprepare_observer() != nullptr &&
5852
5/6
✓ Branch 0 taken 42531 times.
✓ Branch 1 taken 108850 times.
✓ Branch 2 taken 42530 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 37717 times.
✓ Branch 5 taken 113664 times.
193912 thd->get_reprepare_observer()->is_invalidated() &&
5853
4/6
✓ Branch 0 taken 37721 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37721 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 37717 times.
✓ Branch 5 taken 4 times.
37720 thd->get_reprepare_observer()->can_retry())
5854 37717 thd->skip_gtid_rollback = true;
5855 } else {
5856 21211289 lex->set_exec_started();
5857 }
5858
5859 // Cleanup EXPLAIN info
5860
2/2
✓ Branch 0 taken 21238249 times.
✓ Branch 1 taken 124037 times.
21362286 if (!thd->in_sub_stmt) {
5861
3/4
✓ Branch 0 taken 21238521 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16566747 times.
✓ Branch 3 taken 4671774 times.
21238249 if (is_explainable_query(lex->sql_command)) {
5862
3/4
✓ Branch 0 taken 14703542 times.
✓ Branch 1 taken 1863198 times.
✓ Branch 2 taken 14703753 times.
✗ Branch 3 not taken.
16566747 DEBUG_SYNC(thd, "before_reset_query_plan");
5863 /*
5864 We want EXPLAIN CONNECTION to work until the explained statement ends,
5865 thus it is only now that we may fully clean up any unit of this
5866 statement.
5867 */
5868
1/2
✓ Branch 0 taken 16566933 times.
✗ Branch 1 not taken.
16566951 lex->unit->assert_not_fully_clean();
5869 }
5870
1/2
✓ Branch 0 taken 21239987 times.
✗ Branch 1 not taken.
21238707 thd->query_plan.set_query_plan(SQLCOM_END, nullptr, false);
5871 }
5872
5873
3/4
✓ Branch 0 taken 7169096 times.
✓ Branch 1 taken 14194911 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7169041 times.
21364024 assert(!thd->in_active_multi_stmt_transaction() ||
5874 thd->in_multi_stmt_transaction_mode());
5875
5876
2/2
✓ Branch 0 taken 21239634 times.
✓ Branch 1 taken 124318 times.
21363952 if (!thd->in_sub_stmt) {
5877
5/6
✓ Branch 0 taken 13648535 times.
✓ Branch 1 taken 7591099 times.
✓ Branch 2 taken 13648536 times.
✓ Branch 3 taken 7591098 times.
✓ Branch 4 taken 21239663 times.
✗ Branch 5 not taken.
21239634 mysql_audit_notify(thd,
5878 first_level ? MYSQL_AUDIT_QUERY_STATUS_END
5879 : MYSQL_AUDIT_QUERY_NESTED_STATUS_END,
5880 first_level ? "MYSQL_AUDIT_QUERY_STATUS_END"
5881 : "MYSQL_AUDIT_QUERY_NESTED_STATUS_END");
5882
5883 /* report error issued during command execution */
5884
7/8
✓ Branch 0 taken 21239805 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 160715 times.
✓ Branch 3 taken 21079090 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 160713 times.
✓ Branch 6 taken 160716 times.
✓ Branch 7 taken 21079089 times.
42318755 if ((thd->is_error() && !early_error_on_rep_command) ||
5885
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21079094 times.
21079092 (thd->variables.option_bits & OPTION_MASTER_SQL_ERROR))
5886
1/2
✓ Branch 0 taken 160716 times.
✗ Branch 1 not taken.
160716 trans_rollback_stmt(thd);
5887 else {
5888 /* If commit fails, we should be able to reset the OK status. */
5889 21079089 thd->get_stmt_da()->set_overwrite_status(true);
5890
1/2
✓ Branch 0 taken 21078088 times.
✗ Branch 1 not taken.
21078847 trans_commit_stmt(thd);
5891 21078088 thd->get_stmt_da()->set_overwrite_status(false);
5892 }
5893 /*
5894 Reset thd killed flag during cleanup so that commands which are
5895 dispatched using service session API's start with a clean state.
5896 */
5897
5/6
✓ Branch 0 taken 21238432 times.
✓ Branch 1 taken 637 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 21238787 times.
✓ Branch 4 taken 616 times.
✓ Branch 5 taken 21238787 times.
21239291 if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_TIMEOUT) {
5898 616 thd->killed = THD::NOT_KILLED;
5899
1/2
✓ Branch 0 taken 616 times.
✗ Branch 1 not taken.
616 thd->reset_query_for_display();
5900 }
5901 }
5902
5903
1/2
✓ Branch 0 taken 21363170 times.
✗ Branch 1 not taken.
21363721 lex->cleanup(thd, true);
5904
5905 /* Free tables */
5906
1/2
✓ Branch 0 taken 21363214 times.
✗ Branch 1 not taken.
21363170 THD_STAGE_INFO(thd, stage_closing_tables);
5907
1/2
✓ Branch 0 taken 21362775 times.
✗ Branch 1 not taken.
21363214 close_thread_tables(thd);
5908
5909 // Rollback any item transformations made during optimization and execution
5910
1/2
✓ Branch 0 taken 21363666 times.
✗ Branch 1 not taken.
21362775 thd->rollback_item_tree_changes();
5911
5912 #ifndef NDEBUG
5913
4/4
✓ Branch 0 taken 19859200 times.
✓ Branch 1 taken 1504466 times.
✓ Branch 2 taken 19780007 times.
✓ Branch 3 taken 79193 times.
21363666 if (lex->sql_command != SQLCOM_SET_OPTION && !thd->in_sub_stmt)
5914
3/4
✓ Branch 0 taken 17758966 times.
✓ Branch 1 taken 2019940 times.
✓ Branch 2 taken 17759189 times.
✗ Branch 3 not taken.
19780007 DEBUG_SYNC(thd, "execute_command_after_close_tables");
5915 #endif
5916
5917
12/14
✓ Branch 0 taken 21363298 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2904852 times.
✓ Branch 3 taken 18458446 times.
✓ Branch 4 taken 329197 times.
✓ Branch 5 taken 2575655 times.
✓ Branch 6 taken 279432 times.
✓ Branch 7 taken 49765 times.
✓ Branch 8 taken 279173 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 5 times.
✓ Branch 11 taken 279168 times.
✓ Branch 12 taken 5 times.
✓ Branch 13 taken 21362524 times.
21362788 WSREP_NBO_2ND_PHASE_BEGIN;
5918
5919
4/4
✓ Branch 0 taken 21238363 times.
✓ Branch 1 taken 124161 times.
✓ Branch 2 taken 479 times.
✓ Branch 3 taken 21237884 times.
21362524 if (!thd->in_sub_stmt && thd->transaction_rollback_request) {
5920 /*
5921 We are not in sub-statement and transaction rollback was requested by
5922 one of storage engines (e.g. due to deadlock). Rollback transaction in
5923 all storage engines including binary log.
5924 */
5925
1/2
✓ Branch 0 taken 479 times.
✗ Branch 1 not taken.
479 trans_rollback_implicit(thd);
5926
1/2
✓ Branch 0 taken 479 times.
✗ Branch 1 not taken.
479 thd->mdl_context.release_transactional_locks();
5927
3/4
✓ Branch 0 taken 21362355 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1266742 times.
✓ Branch 3 taken 20095613 times.
21362045 } else if (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END)) {
5928 /* No transaction control allowed in sub-statements. */
5929
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1266742 times.
1266742 assert(!thd->in_sub_stmt);
5930 /* If commit fails, we should be able to reset the OK status. */
5931 1266742 thd->get_stmt_da()->set_overwrite_status(true);
5932 /* Commit the normal transaction if one is active. */
5933
1/2
✓ Branch 0 taken 1266782 times.
✗ Branch 1 not taken.
1266767 trans_commit_implicit(thd);
5934 1266782 thd->get_stmt_da()->set_overwrite_status(false);
5935
1/2
✓ Branch 0 taken 1265888 times.
✗ Branch 1 not taken.
1266704 thd->mdl_context.release_transactional_locks();
5936
6/6
✓ Branch 0 taken 19970710 times.
✓ Branch 1 taken 124903 times.
✓ Branch 2 taken 12656887 times.
✓ Branch 3 taken 7314317 times.
✓ Branch 4 taken 12657015 times.
✓ Branch 5 taken 7439092 times.
20095613 } else if (!thd->in_sub_stmt && !thd->in_multi_stmt_transaction_mode()) {
5937 /*
5938 - If inside a multi-statement transaction,
5939 defer the release of metadata locks until the current
5940 transaction is either committed or rolled back. This prevents
5941 other statements from modifying the table for the entire
5942 duration of this transaction. This provides commit ordering
5943 and guarantees serializability across multiple transactions.
5944 - If in autocommit mode, or outside a transactional context,
5945 automatically release metadata locks of the current statement.
5946 */
5947
1/2
✓ Branch 0 taken 12658062 times.
✗ Branch 1 not taken.
12657015 thd->mdl_context.release_transactional_locks();
5948
2/2
✓ Branch 0 taken 7314325 times.
✓ Branch 1 taken 124767 times.
7439092 } else if (!thd->in_sub_stmt &&
5949
2/2
✓ Branch 0 taken 16012 times.
✓ Branch 1 taken 7298313 times.
7314325 (thd->lex->sql_command != SQLCOM_CREATE_TABLE ||
5950
2/2
✓ Branch 0 taken 15943 times.
✓ Branch 1 taken 69 times.
16012 !thd->lex->create_info->m_transactional_ddl)) {
5951
1/2
✓ Branch 0 taken 7314575 times.
✗ Branch 1 not taken.
7314256 thd->mdl_context.release_statement_locks();
5952 }
5953
5954 #ifdef WITH_WSREP
5955
5956 21363840 thd->wsrep_consistency_check = NO_CONSISTENCY_CHECK;
5957
18/24
✓ Branch 0 taken 21363840 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2904889 times.
✓ Branch 3 taken 18458951 times.
✓ Branch 4 taken 329231 times.
✓ Branch 5 taken 2575658 times.
✓ Branch 6 taken 279454 times.
✓ Branch 7 taken 49777 times.
✓ Branch 8 taken 279439 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 272562 times.
✓ Branch 11 taken 6877 times.
✓ Branch 12 taken 21356964 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 21357117 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 21357088 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 26 times.
✓ Branch 19 taken 21357062 times.
✓ Branch 20 taken 6750 times.
✓ Branch 21 taken 21357062 times.
✓ Branch 22 taken 6407 times.
✗ Branch 23 not taken.
21363840 WSREP_TO_ISOLATION_END;
5958
5959 /*
5960 Force release of transactional locks if not in active MST and wsrep is on.
5961 */
5962
8/8
✓ Branch 0 taken 2904886 times.
✓ Branch 1 taken 18459032 times.
✓ Branch 2 taken 329228 times.
✓ Branch 3 taken 2575658 times.
✓ Branch 4 taken 279498 times.
✓ Branch 5 taken 49730 times.
✓ Branch 6 taken 277985 times.
✓ Branch 7 taken 1513 times.
21363918 if (WSREP(thd) && !thd->in_sub_stmt &&
5963
5/6
✓ Branch 0 taken 21363918 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 240768 times.
✓ Branch 3 taken 37215 times.
✓ Branch 4 taken 49 times.
✓ Branch 5 taken 21363407 times.
42968144 !thd->in_active_multi_stmt_transaction() &&
5964
3/4
✓ Branch 0 taken 240757 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49 times.
✓ Branch 3 taken 240708 times.
240768 thd->mdl_context.has_transactional_locks()) {
5965
12/24
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 13 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 13 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 13 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
49 WSREP_DEBUG("Forcing release of transactional locks for thd %u",
5966 thd->thread_id());
5967
1/2
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
49 thd->mdl_context.release_transactional_locks();
5968 }
5969
5970 /*
5971 Current command did not start multi STMT transaction and the command
5972 did not cause commit to happen (e.g. read only). Commit the wsrep
5973 transaction as empty.
5974 */
5975
2/2
✓ Branch 0 taken 14101956 times.
✓ Branch 1 taken 93958 times.
35559370 if (!thd->in_active_multi_stmt_transaction() && !thd->in_sub_stmt &&
5976
9/10
✓ Branch 0 taken 14195914 times.
✓ Branch 1 taken 7167301 times.
✓ Branch 2 taken 14102066 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 127449 times.
✓ Branch 5 taken 13974617 times.
✓ Branch 6 taken 99591 times.
✓ Branch 7 taken 28018 times.
✓ Branch 8 taken 99591 times.
✓ Branch 9 taken 21263894 times.
35686738 thd->wsrep_trx().active() &&
5977 127449 thd->wsrep_trx().state() == wsrep::transaction::s_executing) {
5978
1/2
✓ Branch 0 taken 99591 times.
✗ Branch 1 not taken.
99591 wsrep_commit_empty(thd, true);
5979 }
5980
5981 /* assume PA safety for next transaction */
5982 21363485 thd->wsrep_PA_safe = true;
5983 #endif /* WITH_WSREP */
5984
5985 // If the client wishes to have transaction state reported, we add whatever
5986 // is set on THD to our set here.
5987 {
5988
1/2
✓ Branch 0 taken 21363573 times.
✗ Branch 1 not taken.
21363485 TX_TRACKER_GET(tst);
5989
5990
2/2
✓ Branch 0 taken 213 times.
✓ Branch 1 taken 21363360 times.
21363573 if (thd->variables.session_track_transaction_info > TX_TRACK_NONE)
5991
1/2
✓ Branch 0 taken 213 times.
✗ Branch 1 not taken.
213 tst->add_trx_state_from_thd(thd);
5992
5993 // We're done. Clear "is DML" flag.
5994
1/2
✓ Branch 0 taken 21363781 times.
✗ Branch 1 not taken.
21363573 tst->clear_trx_state(thd, TX_STMT_DML);
5995 }
5996
5997 #ifdef HAVE_LSAN_DO_RECOVERABLE_LEAK_CHECK
5998 // Get incremental leak reports, for easier leak hunting.
5999 // ./mtr --mem --mysqld='-T 4096' --sanitize main.1st
6000 // Don't waste time calling leak sanitizer during bootstrap.
6001 if (!opt_initialize && (test_flags & TEST_DO_QUICK_LEAK_CHECK)) {
6002 int have_leaks = __lsan_do_recoverable_leak_check();
6003 if (have_leaks > 0) {
6004 fprintf(stderr, "LSAN found leaks for Query: %*s\n",
6005 static_cast<int>(thd->query().length), thd->query().str);
6006 fflush(stderr);
6007 }
6008 }
6009 #endif
6010
6011 #if defined(VALGRIND_DO_QUICK_LEAK_CHECK)
6012 // Get incremental leak reports, for easier leak hunting.
6013 // ./mtr --mem --mysqld='-T 4096' --valgrind-mysqld main.1st
6014 // Note that with multiple connections, the report below may be misleading.
6015 if (test_flags & TEST_DO_QUICK_LEAK_CHECK) {
6016 static unsigned long total_leaked_bytes = 0;
6017 unsigned long leaked = 0;
6018 unsigned long dubious [[maybe_unused]];
6019 unsigned long reachable [[maybe_unused]];
6020 unsigned long suppressed [[maybe_unused]];
6021 /*
6022 We could possibly use VALGRIND_DO_CHANGED_LEAK_CHECK here,
6023 but that is a fairly new addition to the Valgrind api.
6024 Note: we dont want to check 'reachable' until we have done shutdown,
6025 and that is handled by the final report anyways.
6026 We print some extra information, to tell mtr to ignore this report.
6027 */
6028 LogErr(INFORMATION_LEVEL, ER_VALGRIND_DO_QUICK_LEAK_CHECK);
6029 VALGRIND_DO_QUICK_LEAK_CHECK;
6030 VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed);
6031 if (leaked > total_leaked_bytes) {
6032 LogErr(ERROR_LEVEL, ER_VALGRIND_COUNT_LEAKS, leaked - total_leaked_bytes,
6033 static_cast<int>(thd->query().length), thd->query().str);
6034 }
6035 total_leaked_bytes = leaked;
6036 }
6037 #endif
6038
6039
7/8
✓ Branch 0 taken 21212463 times.
✓ Branch 1 taken 151318 times.
✓ Branch 2 taken 21212544 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 21200749 times.
✓ Branch 5 taken 11795 times.
✓ Branch 6 taken 21200742 times.
✓ Branch 7 taken 163120 times.
21363781 if (!res && !thd->is_error()) { // if statement succeeded
6040
1/2
✓ Branch 0 taken 21200962 times.
✗ Branch 1 not taken.
21200742 binlog_gtid_end_transaction(thd); // finalize GTID life-cycle
6041
3/4
✓ Branch 0 taken 19123077 times.
✓ Branch 1 taken 2077506 times.
✓ Branch 2 taken 19123336 times.
✗ Branch 3 not taken.
21200962 DEBUG_SYNC(thd, "persist_new_state_after_statement_succeeded");
6042
2/2
✓ Branch 0 taken 163087 times.
✓ Branch 1 taken 33 times.
163120 } else if (!gtid_consistency_violation_state && // if the consistency state
6043
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 162841 times.
163087 thd->has_gtid_consistency_violation) { // was set by the failing
6044 // statement
6045
1/2
✓ Branch 0 taken 246 times.
✗ Branch 1 not taken.
246 gtid_state->end_gtid_violating_transaction(thd); // just roll it back
6046
2/4
✓ Branch 0 taken 246 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 313 times.
✗ Branch 3 not taken.
246 DEBUG_SYNC(thd, "restore_previous_state_after_statement_failed");
6047 }
6048
6049 21364029 thd->skip_gtid_rollback = false;
6050
6051
5/6
✓ Branch 0 taken 21212676 times.
✓ Branch 1 taken 151353 times.
✓ Branch 2 taken 21212696 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11835 times.
✓ Branch 5 taken 21200861 times.
21364029 return res || thd->is_error();
6052 21390175 }
6053
6054 /**
6055 Do special checking for SHOW statements.
6056
6057 @param thd Thread context.
6058 @param lex LEX for SHOW statement.
6059 @param lock If true, lock metadata for schema objects
6060
6061 @returns false if check is successful, true if error
6062 */
6063
6064 bool show_precheck(THD *thd, LEX *lex, bool lock [[maybe_unused]]) {
6065 assert(lex->sql_command == SQLCOM_SHOW_CREATE_USER);
6066 TABLE_LIST *const tables = lex->query_tables;
6067 if (tables != nullptr) {
6068 if (check_table_access(thd, SELECT_ACL, tables, false, UINT_MAX, false))
6069 return true;
6070 }
6071 return false;
6072 }
6073
6074 #define MY_YACC_INIT 1000 // Start with big alloc
6075 #define MY_YACC_MAX 32000 // Because of 'short'
6076
6077 4447 bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, YYLTYPE **yyls,
6078 ulong *yystacksize) {
6079 4447 Yacc_state *state = &current_thd->m_parser_state->m_yacc;
6080 4447 ulong old_info = 0;
6081
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4447 times.
4447 assert(state);
6082
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4447 times.
4447 if ((uint)*yystacksize >= MY_YACC_MAX) return true;
6083
2/2
✓ Branch 0 taken 3031 times.
✓ Branch 1 taken 1416 times.
4447 if (!state->yacc_yyvs) old_info = *yystacksize;
6084 4447 *yystacksize = set_zone((*yystacksize) * 2, MY_YACC_INIT, MY_YACC_MAX);
6085 8894 if (!(state->yacc_yyvs =
6086 8894 (uchar *)my_realloc(key_memory_bison_stack, state->yacc_yyvs,
6087 4447 *yystacksize * sizeof(**yyvs),
6088 4447 MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) ||
6089 4447 !(state->yacc_yyss =
6090
1/2
✓ Branch 0 taken 4447 times.
✗ Branch 1 not taken.
4447 (uchar *)my_realloc(key_memory_bison_stack, state->yacc_yyss,
6091 4447 *yystacksize * sizeof(**yyss),
6092
2/4
✓ Branch 0 taken 4447 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4447 times.
8894 MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) ||
6093 4447 !(state->yacc_yyls =
6094
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4447 times.
4447 (uchar *)my_realloc(key_memory_bison_stack, state->yacc_yyls,
6095 4447 *yystacksize * sizeof(**yyls),
6096 MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))))
6097 return true;
6098
2/2
✓ Branch 0 taken 3031 times.
✓ Branch 1 taken 1416 times.
4447 if (old_info) {
6099 /*
6100 Only copy the old stack on the first call to my_yyoverflow(),
6101 when replacing a static stack (YYINITDEPTH) by a dynamic stack.
6102 For subsequent calls, my_realloc already did preserve the old stack.
6103 */
6104 3031 memcpy(state->yacc_yyss, *yyss, old_info * sizeof(**yyss));
6105 3031 memcpy(state->yacc_yyvs, *yyvs, old_info * sizeof(**yyvs));
6106 3031 memcpy(state->yacc_yyls, *yyls, old_info * sizeof(**yyls));
6107 }
6108 4447 *yyss = (short *)state->yacc_yyss;
6109 4447 *yyvs = (YYSTYPE *)state->yacc_yyvs;
6110 4447 *yyls = (YYLTYPE *)state->yacc_yyls;
6111 4447 return false;
6112 }
6113
6114 /**
6115 Reset the part of THD responsible for the state of command
6116 processing.
6117
6118 This needs to be called before execution of every statement
6119 (prepared or conventional). It is not called by substatements of
6120 routines.
6121
6122 @todo Remove mysql_reset_thd_for_next_command and only use the
6123 member function.
6124
6125 @todo Call it after we use THD for queries, not before.
6126 */
6127 14626142 void mysql_reset_thd_for_next_command(THD *thd) {
6128 14626142 thd->reset_for_next_command();
6129 14627340 }
6130
6131 14792479 void THD::reset_for_next_command() {
6132 // TODO: Why on earth is this here?! We should probably fix this
6133 // function and move it to the proper file. /Matz
6134 14792479 THD *thd = this;
6135
1/2
✓ Branch 0 taken 14793526 times.
✗ Branch 1 not taken.
14792479 DBUG_TRACE;
6136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14793526 times.
14793526 assert(!thd->sp_runtime_ctx); /* not for substatements of routines */
6137
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14793526 times.
14793526 assert(!thd->in_sub_stmt);
6138 14793526 thd->reset_item_list();
6139 /*
6140 Those two lines below are theoretically unneeded as
6141 THD::cleanup_after_query() should take care of this already.
6142 */
6143 14792791 thd->auto_inc_intervals_in_cur_stmt_for_binlog.clear();
6144 14793115 thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt = false;
6145
6146 #ifdef WITH_WSREP
6147 /*
6148 Autoinc variables should be adjusted only for locally executed
6149 transactions. Appliers and replayers are either processing ROW
6150 events or get autoinc variable values from Query_log_event and
6151 mysql slave may be processing STATEMENT format events, but it should
6152 use autoinc values passed in binlog events, not the values forced by
6153 the cluster.
6154 */
6155
16/18
✓ Branch 0 taken 14793175 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 443544 times.
✓ Branch 3 taken 14349631 times.
✓ Branch 4 taken 377793 times.
✓ Branch 5 taken 65751 times.
✓ Branch 6 taken 361559 times.
✓ Branch 7 taken 16234 times.
✓ Branch 8 taken 361565 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 191810 times.
✓ Branch 11 taken 169755 times.
✓ Branch 12 taken 190077 times.
✓ Branch 13 taken 1733 times.
✓ Branch 14 taken 190028 times.
✓ Branch 15 taken 49 times.
✓ Branch 16 taken 190028 times.
✓ Branch 17 taken 14603093 times.
14793115 if (WSREP(thd) && wsrep_thd_is_local(thd) && !thd->slave_thread &&
6156 wsrep_auto_increment_control) {
6157 190028 thd->variables.auto_increment_offset =
6158 190028 global_system_variables.auto_increment_offset;
6159 190028 thd->variables.auto_increment_increment =
6160 190028 global_system_variables.auto_increment_increment;
6161 }
6162 #endif /* WITH_WSREP */
6163
6164 14793121 thd->query_start_usec_used = false;
6165 14793121 thd->m_is_fatal_error = false;
6166 14793121 thd->time_zone_used = false;
6167 /*
6168 Clear the status flag that are expected to be cleared at the
6169 beginning of each SQL statement.
6170 */
6171 14793121 thd->server_status &= ~SERVER_STATUS_CLEAR_SET;
6172 /*
6173 If in autocommit mode and not in a transaction, reset flag
6174 that identifies if a transaction has done some operations
6175 that cannot be safely rolled back.
6176
6177 If the flag is set an warning message is printed out in
6178 ha_rollback_trans() saying that some tables couldn't be
6179 rolled back.
6180 */
6181
2/2
✓ Branch 0 taken 11261158 times.
✓ Branch 1 taken 3531765 times.
14793121 if (!thd->in_multi_stmt_transaction_mode()) {
6182
1/2
✓ Branch 0 taken 11261144 times.
✗ Branch 1 not taken.
11261158 thd->get_transaction()->reset_unsafe_rollback_flags(
6183 Transaction_ctx::SESSION);
6184 }
6185
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14793189 times.
14792909 assert(thd->security_context() == &thd->m_main_security_ctx);
6186 14793189 thd->thread_specific_used = false;
6187
6188
2/2
✓ Branch 0 taken 12780961 times.
✓ Branch 1 taken 2012228 times.
14793189 if (opt_bin_log) {
6189
1/2
✓ Branch 0 taken 12780612 times.
✗ Branch 1 not taken.
12780961 thd->user_var_events.clear();
6190 12780612 thd->user_var_events_alloc = thd->mem_root;
6191 }
6192
1/2
✓ Branch 0 taken 14793652 times.
✗ Branch 1 not taken.
14792840 thd->clear_error();
6193
1/2
✓ Branch 0 taken 14793675 times.
✗ Branch 1 not taken.
14793652 thd->get_stmt_da()->reset_diagnostics_area();
6194 14793675 thd->get_stmt_da()->reset_statement_cond_count();
6195
6196 14793147 thd->rand_used = false;
6197
6198 14793147 thd->clear_slow_extended();
6199
6200
1/2
✓ Branch 0 taken 14793689 times.
✗ Branch 1 not taken.
14793652 thd->reset_current_stmt_binlog_format_row();
6201 14793689 thd->binlog_unsafe_warning_flags = 0;
6202 14793689 thd->binlog_need_explicit_defaults_ts = false;
6203
6204 14793689 thd->commit_error = THD::CE_NONE;
6205 14793689 thd->durability_property = HA_REGULAR_DURABILITY;
6206
1/2
✓ Branch 0 taken 14793646 times.
✗ Branch 1 not taken.
14793689 thd->set_trans_pos(nullptr, 0);
6207 14793646 thd->derived_tables_processing = false;
6208 14793646 thd->parsing_system_view = false;
6209
6210 // Need explicit setting, else demand all privileges to a table.
6211 14793646 thd->want_privilege = ~NO_ACCESS;
6212
6213 14793646 thd->reset_skip_readonly_check();
6214 14792884 thd->tx_commit_pending = false;
6215
6216
5/8
✓ Branch 0 taken 14793254 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14793346 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 197 times.
✓ Branch 5 taken 14793149 times.
✓ Branch 6 taken 197 times.
✗ Branch 7 not taken.
14792884 DBUG_PRINT("debug", ("is_current_stmt_binlog_format_row(): %d",
6217 thd->is_current_stmt_binlog_format_row()));
6218
6219 /*
6220 In case we're processing multiple statements we need to checkout a new
6221 acl access map here as the global acl version might have increased due to
6222 a grant/revoke or flush.
6223 */
6224
1/2
✓ Branch 0 taken 14793191 times.
✗ Branch 1 not taken.
14793346 thd->security_context()->checkout_access_maps();
6225 #ifndef NDEBUG
6226 14793191 thd->set_tmp_table_seq_id(1);
6227 #endif
6228 14792928 }
6229
6230 /*
6231 When you modify dispatch_sql_command(), you may need to modify
6232 mysql_test_parse_for_slave() in this same file.
6233 */
6234
6235 /**
6236 Parse an SQL command from a text string and pass the resulting AST to the
6237 query executor.
6238
6239 @param thd Current session.
6240 @param parser_state Parser state.
6241 */
6242
6243 13554440 void dispatch_sql_command(THD *thd, Parser_state *parser_state,
6244 bool update_userstat) {
6245
1/2
✓ Branch 0 taken 13555566 times.
✗ Branch 1 not taken.
13554440 DBUG_TRACE;
6246
6/10
✓ Branch 0 taken 13555096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13555486 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 180 times.
✓ Branch 5 taken 13555306 times.
✓ Branch 6 taken 180 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 180 times.
✗ Branch 9 not taken.
13555566 DBUG_PRINT("dispatch_sql_command", ("query: '%s'", thd->query().str));
6247
6248
2/6
✓ Branch 0 taken 13555345 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 13555345 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
13555486 DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on(););
6249
6250
1/2
✓ Branch 0 taken 13555657 times.
✗ Branch 1 not taken.
13555345 mysql_reset_thd_for_next_command(thd);
6251
1/2
✓ Branch 0 taken 13555165 times.
✗ Branch 1 not taken.
13555657 lex_start(thd);
6252
6253 /* Declare userstat variables and start timer */
6254 13555165 double start_busy_usecs = 0.0;
6255 13555165 double start_cpu_nsecs = 0.0;
6256
6/6
✓ Branch 0 taken 11129 times.
✓ Branch 1 taken 13544036 times.
✓ Branch 2 taken 9454 times.
✓ Branch 3 taken 1675 times.
✓ Branch 4 taken 9454 times.
✓ Branch 5 taken 13545696 times.
13555165 if (unlikely(opt_userstat && update_userstat))
6257 9454 userstat_start_timer(&start_busy_usecs, &start_cpu_nsecs);
6258
6259 13555150 thd->m_parser_state = parser_state;
6260
1/2
✓ Branch 0 taken 13554911 times.
✗ Branch 1 not taken.
13555150 invoke_pre_parse_rewrite_plugins(thd);
6261 13554911 thd->m_parser_state = nullptr;
6262
6263 // we produce digest if it's not explicitly turned off
6264 // by setting maximum digest length to zero
6265
2/4
✓ Branch 0 taken 13554256 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13554289 times.
✗ Branch 3 not taken.
13554911 if (get_max_digest_length() != 0)
6266 13554289 parser_state->m_input.m_compute_digest = true;
6267
6268 13554256 LEX *lex = thd->lex;
6269 13554256 const char *found_semicolon = nullptr;
6270
6271 13554256 bool err = thd->get_stmt_da()->is_error();
6272
6273
1/2
✓ Branch 0 taken 13554953 times.
✗ Branch 1 not taken.
13554944 if (!err) {
6274
1/2
✓ Branch 0 taken 13555152 times.
✗ Branch 1 not taken.
13554953 err = parse_sql(thd, parser_state, nullptr);
6275
3/4
✓ Branch 0 taken 13547447 times.
✓ Branch 1 taken 7705 times.
✓ Branch 2 taken 13546976 times.
✗ Branch 3 not taken.
13555152 if (!err) err = invoke_post_parse_rewrite_plugins(thd, false);
6276
6277 13554681 found_semicolon = parser_state->m_lip.found_semicolon;
6278 }
6279
6280
3/4
✓ Branch 0 taken 11682583 times.
✓ Branch 1 taken 1872089 times.
✓ Branch 2 taken 11683288 times.
✗ Branch 3 not taken.
13554672 DEBUG_SYNC_C("sql_parse_before_rewrite");
6281
6282
2/2
✓ Branch 0 taken 13548134 times.
✓ Branch 1 taken 7243 times.
13555377 if (!err) {
6283 /*
6284 Rewrite the query for logging and for the Performance Schema
6285 statement tables. (Raw logging happened earlier.)
6286
6287 Sub-routines of mysql_rewrite_query() should try to only rewrite when
6288 necessary (e.g. not do password obfuscation when query contains no
6289 password).
6290
6291 If rewriting does not happen here, thd->m_rewritten_query is still
6292 empty from being reset in alloc_query().
6293 */
6294
4/6
✓ Branch 0 taken 13547644 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11722663 times.
✓ Branch 3 taken 1824921 times.
✓ Branch 4 taken 11722216 times.
✗ Branch 5 not taken.
13548134 if (thd->rewritten_query().length() == 0) mysql_rewrite_query(thd);
6295
6296
3/4
✓ Branch 0 taken 13547725 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1839503 times.
✓ Branch 3 taken 11708331 times.
13547137 if (thd->rewritten_query().length()) {
6297 1839503 lex->safe_to_cache_query = false; // see comments below
6298
6299
2/4
✓ Branch 0 taken 1838470 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1838511 times.
✗ Branch 3 not taken.
1838470 thd->set_query_for_display(thd->rewritten_query().ptr(),
6300
1/2
✓ Branch 0 taken 1838470 times.
✗ Branch 1 not taken.
1839503 thd->rewritten_query().length());
6301
2/2
✓ Branch 0 taken 523153 times.
✓ Branch 1 taken 11185178 times.
11708331 } else if (thd->slave_thread) {
6302 /*
6303 In the slave, we add the information to pfs.events_statements_history,
6304 but not to pfs.threads, as that is what the test suite expects.
6305 */
6306
3/6
✓ Branch 0 taken 523146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 523375 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 523255 times.
✗ Branch 5 not taken.
523153 MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, thd->query().str,
6307 thd->query().length);
6308 } else {
6309
3/6
✓ Branch 0 taken 11185553 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11185744 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11186380 times.
✗ Branch 5 not taken.
11185178 thd->set_query_for_display(thd->query().str, thd->query().length);
6310 }
6311
6312
4/4
✓ Branch 0 taken 13547908 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 13024648 times.
✓ Branch 3 taken 523260 times.
13548146 if (!(opt_general_log_raw || thd->slave_thread)) {
6313
3/4
✓ Branch 0 taken 13024520 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1839082 times.
✓ Branch 3 taken 11185447 times.
13024648 if (thd->rewritten_query().length())
6314
1/2
✓ Branch 0 taken 1838334 times.
✗ Branch 1 not taken.
1838459 query_logger.general_log_write(thd, COM_QUERY,
6315
1/2
✓ Branch 0 taken 1838459 times.
✗ Branch 1 not taken.
1838459 thd->rewritten_query().ptr(),
6316
1/2
✓ Branch 0 taken 1838459 times.
✗ Branch 1 not taken.
1839082 thd->rewritten_query().length());
6317 else {
6318
3/4
✓ Branch 0 taken 80935 times.
✓ Branch 1 taken 11104512 times.
✓ Branch 2 taken 80935 times.
✗ Branch 3 not taken.
11185447 size_t qlen = found_semicolon ? (found_semicolon - thd->query().str)
6319
1/2
✓ Branch 0 taken 11104889 times.
✗ Branch 1 not taken.
11104512 : thd->query().length;
6320
6321
2/4
✓ Branch 0 taken 11185735 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11186074 times.
✗ Branch 3 not taken.
11185824 query_logger.general_log_write(thd, COM_QUERY, thd->query().str, qlen);
6322 }
6323 }
6324 }
6325
6326
3/4
✓ Branch 0 taken 11683048 times.
✓ Branch 1 taken 1872101 times.
✓ Branch 2 taken 11683610 times.
✗ Branch 3 not taken.
13555149 DEBUG_SYNC_C("sql_parse_after_rewrite");
6327
6328
2/2
✓ Branch 0 taken 13548420 times.
✓ Branch 1 taken 7291 times.
13555711 if (!err) {
6329
1/2
✓ Branch 0 taken 13548224 times.
✗ Branch 1 not taken.
13548420 thd->m_statement_psi = MYSQL_REFINE_STATEMENT(
6330 thd->m_statement_psi, sql_statement_info[thd->lex->sql_command].m_key);
6331
6332
6/6
✓ Branch 0 taken 77878 times.
✓ Branch 1 taken 13470346 times.
✓ Branch 2 taken 304 times.
✓ Branch 3 taken 77574 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 13548199 times.
13548507 if (mqh_used && thd->get_user_connect() &&
6333
3/4
✓ Branch 0 taken 283 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 279 times.
304 check_mqh(thd, lex->sql_command)) {
6334
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if (thd->is_classic_protocol())
6335
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 thd->get_protocol_classic()->get_net()->error = NET_ERROR_UNSET;
6336 } else {
6337
3/4
✓ Branch 0 taken 13548264 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13548246 times.
✓ Branch 3 taken 18 times.
13548199 if (!thd->is_error()) {
6338 /*
6339 Binlog logs a string starting from thd->query and having length
6340 thd->query_length; so we set thd->query_length correctly (to not
6341 log several statements in one event, when we executed only first).
6342 We set it to not see the ';' (otherwise it would get into binlog
6343 and Query_log_event::print() would give ';;' output).
6344 This also helps display only the current query in SHOW
6345 PROCESSLIST.
6346 */
6347
6/8
✓ Branch 0 taken 80951 times.
✓ Branch 1 taken 13467295 times.
✓ Branch 2 taken 80951 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80951 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80951 times.
✓ Branch 7 taken 13467295 times.
13548246 if (found_semicolon && (ulong)(found_semicolon - thd->query().str))
6348 242853 thd->set_query(
6349
1/2
✓ Branch 0 taken 80951 times.
✗ Branch 1 not taken.
80951 thd->query().str,
6350
2/4
✓ Branch 0 taken 80951 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80951 times.
✗ Branch 3 not taken.
80951 static_cast<size_t>(found_semicolon - thd->query().str - 1));
6351 /* Actually execute the query */
6352
2/2
✓ Branch 0 taken 80951 times.
✓ Branch 1 taken 13467295 times.
13548246 if (found_semicolon) {
6353 80951 lex->safe_to_cache_query = false;
6354 80951 thd->server_status |= SERVER_MORE_RESULTS_EXISTS;
6355 }
6356
1/2
✓ Branch 0 taken 13547256 times.
✗ Branch 1 not taken.
13548246 lex->set_trg_event_type_for_tables();
6357
6358 int error [[maybe_unused]];
6359
2/2
✓ Branch 0 taken 124 times.
✓ Branch 1 taken 13547491 times.
13547481 if (unlikely(
6360
1/2
✓ Branch 0 taken 13547642 times.
✗ Branch 1 not taken.
13547256 (thd->security_context()->password_expired() ||
6361
2/4
✓ Branch 0 taken 13547314 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 13547314 times.
13547475 thd->security_context()->is_in_registration_sandbox_mode()) &&
6362
4/4
✓ Branch 0 taken 13547475 times.
✓ Branch 1 taken 167 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 7 times.
27095116 lex->sql_command != SQLCOM_SET_PASSWORD &&
6363
2/2
✓ Branch 0 taken 124 times.
✓ Branch 1 taken 36 times.
160 lex->sql_command != SQLCOM_ALTER_USER)) {
6364
2/4
✓ Branch 0 taken 124 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 124 times.
124 if (thd->security_context()->is_in_registration_sandbox_mode())
6365 my_error(ER_PLUGIN_REQUIRES_REGISTRATION, MYF(0));
6366 else
6367
1/2
✓ Branch 0 taken 124 times.
✗ Branch 1 not taken.
124 my_error(ER_MUST_CHANGE_PASSWORD, MYF(0));
6368 124 error = 1;
6369 } else {
6370 13547491 resourcegroups::Resource_group *src_res_grp = nullptr;
6371 13547491 resourcegroups::Resource_group *dest_res_grp = nullptr;
6372 13547491 MDL_ticket *ticket = nullptr;
6373 13547491 MDL_ticket *cur_ticket = nullptr;
6374
1/2
✓ Branch 0 taken 13547654 times.
✗ Branch 1 not taken.
13547491 auto mgr_ptr = resourcegroups::Resource_group_mgr::instance();
6375
1/2
✓ Branch 0 taken 13547217 times.
✗ Branch 1 not taken.
13547654 bool switched = mgr_ptr->switch_resource_group_if_needed(
6376 thd, &src_res_grp, &dest_res_grp, &ticket, &cur_ticket);
6377
6378
1/2
✓ Branch 0 taken 13546155 times.
✗ Branch 1 not taken.
13547217 error = mysql_execute_command(thd, true);
6379
6380
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 13546151 times.
13546155 if (switched)
6381
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 mgr_ptr->restore_original_resource_group(thd, src_res_grp,
6382 dest_res_grp);
6383 13546155 thd->resource_group_ctx()->m_switch_resource_group_str[0] = '\0';
6384
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 13546056 times.
13546066 if (ticket != nullptr)
6385
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 mgr_ptr->release_shared_mdl_for_resource_group(thd, ticket);
6386
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 13546064 times.
13546066 if (cur_ticket != nullptr)
6387
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
2 mgr_ptr->release_shared_mdl_for_resource_group(thd, cur_ticket);
6388 }
6389 }
6390 }
6391 } else {
6392 /*
6393 Log the failed raw query in the Performance Schema. This statement did
6394 not parse, so there is no way to tell if it may contain a password of not.
6395
6396 The tradeoff is:
6397 a) If we do log the query, a user typing by accident a broken query
6398 containing a password will have the password exposed. This is very
6399 unlikely, and this behavior can be documented. Remediation is to use
6400 a new password when retyping the corrected query.
6401
6402 b) If we do not log the query, finding broken queries in the client
6403 application will be much more difficult. This is much more likely.
6404
6405 Considering that broken queries can typically be generated by attempts at
6406 SQL injection, finding the source of the SQL injection is critical, so the
6407 design choice is to log the query text of broken queries (a).
6408 */
6409
3/6
✓ Branch 0 taken 7291 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7291 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7291 times.
✗ Branch 5 not taken.
7291 thd->set_query_for_display(thd->query().str, thd->query().length);
6410
6411 /* Instrument this broken statement as "statement/sql/error" */
6412
1/2
✓ Branch 0 taken 7291 times.
✗ Branch 1 not taken.
7291 thd->m_statement_psi = MYSQL_REFINE_STATEMENT(
6413 thd->m_statement_psi, sql_statement_info[SQLCOM_END].m_key);
6414
6415
2/4
✓ Branch 0 taken 7291 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7291 times.
7291 assert(thd->is_error());
6416
3/8
✓ Branch 0 taken 7291 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7291 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 7291 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
7291 DBUG_PRINT("info",
6417 ("Command aborted. Fatal_error: %d", thd->is_fatal_error()));
6418 }
6419
6420
1/2
✓ Branch 0 taken 13553669 times.
✗ Branch 1 not taken.
13553472 THD_STAGE_INFO(thd, stage_freeing_items);
6421
1/2
✓ Branch 0 taken 13553174 times.
✗ Branch 1 not taken.
13553669 sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size);
6422
1/2
✓ Branch 0 taken 13553566 times.
✗ Branch 1 not taken.
13553174 sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size);
6423
1/2
✓ Branch 0 taken 13553547 times.
✗ Branch 1 not taken.
13553566 thd->lex->destroy();
6424
1/2
✓ Branch 0 taken 13553756 times.
✗ Branch 1 not taken.
13553547 thd->end_statement();
6425
1/2
✓ Branch 0 taken 13553755 times.
✗ Branch 1 not taken.
13553756 thd->cleanup_after_query();
6426
2/2
✓ Branch 0 taken 176 times.
✓ Branch 1 taken 13553352 times.
13553755 assert(thd->change_list.is_empty());
6427
6428 /* Update user statistics only if at least one timer was initialized */
6429
4/4
✓ Branch 0 taken 2421062 times.
✓ Branch 1 taken 11132290 times.
✓ Branch 2 taken 9454 times.
✓ Branch 3 taken 13544075 times.
15974414 if (unlikely(update_userstat &&
6430
4/4
✓ Branch 0 taken 2411663 times.
✓ Branch 1 taken 9399 times.
✓ Branch 2 taken 55 times.
✓ Branch 3 taken 2411608 times.
2421062 (start_busy_usecs > 0.0 || start_cpu_nsecs > 0.0))) {
6431 9454 userstat_finish_timer(start_busy_usecs, start_cpu_nsecs, &thd->busy_time,
6432 &thd->cpu_time);
6433 /* Updates THD stats and the global user stats. */
6434 9454 thd->update_stats(true);
6435
1/2
✓ Branch 0 taken 9454 times.
✗ Branch 1 not taken.
9454 update_global_user_stats(thd, true, my_getsystime());
6436 }
6437
6438
3/4
✓ Branch 0 taken 11681359 times.
✓ Branch 1 taken 1872117 times.
✓ Branch 2 taken 11682017 times.
✗ Branch 3 not taken.
13553529 DEBUG_SYNC(thd, "query_rewritten");
6439 13554134 }
6440
6441 /**
6442 Usable by the replication SQL thread only: just parse a query to know if it
6443 can be ignored because of replicate-*-table rules.
6444
6445 @retval
6446 0 cannot be ignored
6447 @retval
6448 1 can be ignored
6449 */
6450
6451 5 bool mysql_test_parse_for_slave(THD *thd) {
6452 5 LEX *lex = thd->lex;
6453 5 bool ignorable = false;
6454 5 sql_digest_state *parent_digest = thd->m_digest;
6455 5 PSI_statement_locker *parent_locker = thd->m_statement_psi;
6456
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 DBUG_TRACE;
6457
6458
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 assert(thd->slave_thread);
6459
6460
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 Parser_state parser_state;
6461
4/8
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
5 if (parser_state.init(thd, thd->query().str, thd->query().length) == 0) {
6462
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 lex_start(thd);
6463
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 mysql_reset_thd_for_next_command(thd);
6464
6465 5 thd->m_digest = nullptr;
6466 5 thd->m_statement_psi = nullptr;
6467
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 if (parse_sql(thd, &parser_state, nullptr) == 0) {
6468
3/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 3 times.
5 if (all_tables_not_ok(thd, lex->query_block->table_list.first))
6469 2 ignorable = true;
6470
3/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2 times.
3 else if (!check_database_filters(thd, thd->db().str, lex->sql_command))
6471 1 ignorable = true;
6472 }
6473 5 thd->m_digest = parent_digest;
6474 5 thd->m_statement_psi = parent_locker;
6475
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 thd->end_statement();
6476 }
6477
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 thd->cleanup_after_query();
6478 5 return ignorable;
6479 5 }
6480
6481 /**
6482 Store field definition for create.
6483
6484 @param thd The thread handler.
6485 @param field_name The field name.
6486 @param type The type of the field.
6487 @param length The length of the field or NULL.
6488 @param decimals The length of a decimal part or NULL.
6489 @param type_modifier Type modifiers & constraint flags of the
6490 field.
6491 @param default_value The default value or NULL.
6492 @param on_update_value The ON UPDATE expression or NULL.
6493 @param comment The comment.
6494 @param change The old column name (if renaming) or NULL.
6495 @param interval_list The list of ENUM/SET values or NULL.
6496 @param cs The character set of the field.
6497 @param has_explicit_collation Column has an explicit COLLATE attribute.
6498 @param uint_geom_type The GIS type of the field.
6499 @param gcol_info The generated column data or NULL.
6500 @param default_val_expr The expression for generating default values,
6501 if there is one, or nullptr.
6502 @param opt_after The name of the field to add after or
6503 the @see first_keyword pointer to insert
6504 first.
6505 @param srid The SRID for this column (only relevant if
6506 this is a geometry column).
6507 @param col_check_const_spec_list List of column check constraints.
6508 @param hidden Column hidden type.
6509 @param is_array Whether it's a typed array field
6510
6511 @return
6512 Return 0 if ok
6513 */
6514 4694037 bool Alter_info::add_field(
6515 THD *thd, const LEX_STRING *field_name, enum_field_types type,
6516 const char *length, const char *decimals, uint type_modifier,
6517 Item *default_value, Item *on_update_value, LEX_CSTRING *comment,
6518 const char *change, List<String> *interval_list, const CHARSET_INFO *cs,
6519 bool has_explicit_collation, uint uint_geom_type,
6520 const LEX_CSTRING *zip_dict, Value_generator *gcol_info,
6521 Value_generator *default_val_expr, const char *opt_after,
6522 std::optional<gis::srid_t> srid,
6523 Sql_check_constraint_spec_list *col_check_const_spec_list,
6524 dd::Column::enum_hidden_type hidden, bool is_array) {
6525
2/2
✓ Branch 0 taken 52124 times.
✓ Branch 1 taken 4641913 times.
4694037 uint8 datetime_precision = decimals ? atoi(decimals) : 0;
6526
1/2
✓ Branch 0 taken 4694038 times.
✗ Branch 1 not taken.
4694037 DBUG_TRACE;
6527
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4694038 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4694038 assert(!is_array || hidden == dd::Column::enum_hidden_type::HT_HIDDEN_SQL);
6528
6529 4694038 LEX_CSTRING field_name_cstr = {field_name->str, field_name->length};
6530
6531
3/4
✓ Branch 0 taken 4694037 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 4694027 times.
4694038 if (check_string_char_length(field_name_cstr, "", NAME_CHAR_LEN,
6532 system_charset_info, true)) {
6533 10 my_error(ER_TOO_LONG_IDENT, MYF(0),
6534
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 field_name->str); /* purecov: inspected */
6535 10 return true; /* purecov: inspected */
6536 }
6537
2/2
✓ Branch 0 taken 57946 times.
✓ Branch 1 taken 4636081 times.
4694027 if (type_modifier & PRI_KEY_FLAG) {
6538 57946 List<Key_part_spec> key_parts;
6539 auto key_part_spec =
6540
1/2
✓ Branch 0 taken 57946 times.
✗ Branch 1 not taken.
57946 new (thd->mem_root) Key_part_spec(field_name_cstr, 0, ORDER_ASC);
6541
4/8
✓ Branch 0 taken 57946 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 57946 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 57946 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 57946 times.
57946 if (key_part_spec == nullptr || key_parts.push_back(key_part_spec))
6542 return true;
6543 Key_spec *key = new (thd->mem_root)
6544 Key_spec(thd->mem_root, KEYTYPE_PRIMARY, NULL_CSTR,
6545
2/4
✓ Branch 0 taken 57946 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 57946 times.
✗ Branch 3 not taken.
57946 &default_key_create_info, false, true, key_parts);
6546
4/8
✓ Branch 0 taken 57946 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 57946 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 57946 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 57946 times.
57946 if (key == nullptr || key_list.push_back(key)) return true;
6547 }
6548
2/2
✓ Branch 0 taken 2673 times.
✓ Branch 1 taken 4691354 times.
4694027 if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG | CLUSTERING_FLAG)) {
6549 enum keytype key_type;
6550
2/2
✓ Branch 0 taken 2671 times.
✓ Branch 1 taken 2 times.
2673 if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
6551 2671 key_type = KEYTYPE_UNIQUE;
6552 else
6553 2 key_type = KEYTYPE_MULTIPLE;
6554
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2667 times.
2673 if (type_modifier & CLUSTERING_FLAG)
6555 6 key_type = static_cast<enum keytype>(key_type | KEYTYPE_CLUSTERING);
6556
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2673 times.
2673 assert(key_type != KEYTYPE_MULTIPLE);
6557 2673 List<Key_part_spec> key_parts;
6558 auto key_part_spec =
6559
1/2
✓ Branch 0 taken 2673 times.
✗ Branch 1 not taken.
2673 new (thd->mem_root) Key_part_spec(field_name_cstr, 0, ORDER_ASC);
6560
4/8
✓ Branch 0 taken 2673 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2673 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2673 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2673 times.
2673 if (key_part_spec == nullptr || key_parts.push_back(key_part_spec))
6561 return true;
6562 Key_spec *key = new (thd->mem_root)
6563 Key_spec(thd->mem_root, key_type, NULL_CSTR, &default_key_create_info,
6564
2/4
✓ Branch 0 taken 2673 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2673 times.
✗ Branch 3 not taken.
2673 false, true, key_parts);
6565
4/8
✓ Branch 0 taken 2673 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2673 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2673 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2673 times.
2673 if (key == nullptr || key_list.push_back(key)) return true;
6566 }
6567
6568
2/2
✓ Branch 0 taken 306489 times.
✓ Branch 1 taken 4387538 times.
4694027 if (default_value) {
6569 /*
6570 Default value should be literal => basic constants =>
6571 no need fix_fields()
6572
6573 We allow only CURRENT_TIMESTAMP as function default for the TIMESTAMP or
6574 DATETIME types. In addition, TRUE and FALSE are allowed for bool types.
6575 */
6576
3/4
✓ Branch 0 taken 306489 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45517 times.
✓ Branch 3 taken 260972 times.
306489 if (default_value->type() == Item::FUNC_ITEM) {
6577 45517 Item_func *func = down_cast<Item_func *>(default_value);
6578
3/4
✓ Branch 0 taken 45517 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1334 times.
✓ Branch 3 taken 44183 times.
45517 if (func->basic_const_item()) {
6579
3/4
✓ Branch 0 taken 1334 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 1329 times.
1334 if (func->result_type() != INT_RESULT) {
6580
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
6581 5 return true;
6582 }
6583
5/8
✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1320 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 1320 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1320 times.
1329 assert(dynamic_cast<Item_func_true *>(func) ||
6584 dynamic_cast<Item_func_false *>(func));
6585
3/6
✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1329 times.
✗ Branch 5 not taken.
1329 default_value = new Item_int(func->val_int());
6586
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1329 times.
1329 if (default_value == nullptr) return true;
6587
1/2
✓ Branch 0 taken 44183 times.
✗ Branch 1 not taken.
44183 } else if (func->functype() != Item_func::NOW_FUNC ||
6588
5/6
✓ Branch 0 taken 44183 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44161 times.
✓ Branch 3 taken 22 times.
✓ Branch 4 taken 60 times.
✓ Branch 5 taken 44123 times.
88344 !real_type_with_now_as_default(type) ||
6589
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 44123 times.
44161 default_value->decimals != datetime_precision) {
6590
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
6591 60 return true;
6592 }
6593
3/4
✓ Branch 0 taken 260972 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 142912 times.
✓ Branch 3 taken 118060 times.
260972 } else if (default_value->type() == Item::NULL_ITEM) {
6594 142912 default_value = nullptr;
6595
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 142910 times.
142912 if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) ==
6596 NOT_NULL_FLAG) {
6597
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
6598 2 return true;
6599 }
6600
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 118059 times.
118060 } else if (type_modifier & AUTO_INCREMENT_FLAG) {
6601
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
6602 1 return true;
6603 }
6604 }
6605
6606 // 1) Reject combinations of DEFAULT <value> and DEFAULT (<expression>).
6607 // 2) Reject combinations of DEFAULT (<expression>) and AUTO_INCREMENT.
6608 // (Combinations of DEFAULT <value> and AUTO_INCREMENT are rejected above.)
6609
6/6
✓ Branch 0 taken 309 times.
✓ Branch 1 taken 4693650 times.
✓ Branch 2 taken 306 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 306 times.
✓ Branch 5 taken 4693650 times.
4693959 if ((default_val_expr && default_value) ||
6610
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 303 times.
306 (default_val_expr && (type_modifier & AUTO_INCREMENT_FLAG))) {
6611
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
6 my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
6612 5 return true;
6613 }
6614
6615
6/6
✓ Branch 0 taken 33832 times.
✓ Branch 1 taken 4660121 times.
✓ Branch 2 taken 33810 times.
✓ Branch 3 taken 22 times.
✓ Branch 4 taken 34 times.
✓ Branch 5 taken 4693919 times.
4727763 if (on_update_value && (!real_type_with_now_on_update(type) ||
6616
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 33798 times.
33810 on_update_value->decimals != datetime_precision)) {
6617
1/2
✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
34 my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name->str);
6618 34 return true;
6619 }
6620
6621 // If the SRID is specified on a non-geometric column, return an error
6622
6/6
✓ Branch 0 taken 4692474 times.
✓ Branch 1 taken 1445 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 4692470 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 4693915 times.
4693919 if (type != MYSQL_TYPE_GEOMETRY && srid.has_value()) {
6623
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 my_error(ER_WRONG_USAGE, MYF(0), "SRID", "non-geometry column");
6624 5 return true;
6625 }
6626
6627
1/2
✓ Branch 0 taken 4693915 times.
✗ Branch 1 not taken.
9387831 Create_field *new_field = new (thd->mem_root) Create_field();
6628
3/4
✓ Branch 0 taken 4693916 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 159 times.
✓ Branch 3 taken 4693757 times.
9387832 if ((new_field == nullptr) ||
6629
3/4
✓ Branch 0 taken 4693916 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 159 times.
✓ Branch 3 taken 4693757 times.
4693916 new_field->init(thd, field_name->str, type, length, decimals,
6630 type_modifier, default_value, on_update_value, comment,
6631 change, interval_list, cs, has_explicit_collation,
6632 uint_geom_type, zip_dict, gcol_info, default_val_expr,
6633 srid, hidden, is_array))
6634 159 return true;
6635
6636
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 4693757 times.
4693862 for (const auto &a : cf_appliers) {
6637
2/4
✓ Branch 0 taken 105 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 105 times.
105 if (a(new_field, this)) return true;
6638 }
6639
6640
1/2
✓ Branch 0 taken 4693757 times.
✗ Branch 1 not taken.
4693757 create_list.push_back(new_field);
6641
2/2
✓ Branch 0 taken 15144 times.
✓ Branch 1 taken 4678613 times.
4693757 if (opt_after != nullptr) {
6642 15144 flags |= Alter_info::ALTER_COLUMN_ORDER;
6643 15144 new_field->after = opt_after;
6644 }
6645
6646
1/2
✓ Branch 0 taken 4693757 times.
✗ Branch 1 not taken.
4693757 if (col_check_const_spec_list) {
6647 /*
6648 Set column name, required for column check constraint validation in
6649 Sql_check_constraint_spec::pre_validate().
6650 */
6651
3/4
✓ Branch 0 taken 4693756 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 207 times.
✓ Branch 3 taken 4693756 times.
4693964 for (auto &cc_spec : *col_check_const_spec_list) {
6652 207 cc_spec->column_name = *field_name;
6653 }
6654 /*
6655 Move column check constraint specifications to table check constraints
6656 specifications list.
6657 */
6658
2/4
✓ Branch 0 taken 4693757 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4693757 times.
✗ Branch 3 not taken.
4693756 std::move(col_check_const_spec_list->begin(),
6659 col_check_const_spec_list->end(),
6660
1/2
✓ Branch 0 taken 4693756 times.
✗ Branch 1 not taken.
4693756 std::back_inserter(check_constraint_spec_list));
6661 }
6662
6663 4693757 return false;
6664 4694038 }
6665
6666 /**
6667 save order by and tables in own lists.
6668 */
6669
6670 void add_to_list(SQL_I_List<ORDER> &list, ORDER *order) {
6671 DBUG_TRACE;
6672 order->used_alias = false;
6673 order->used = 0;
6674 list.link_in_list(order, &order->next);
6675 }
6676
6677 /**
6678 Produces a PT_subquery object from a subquery's text.
6679 @param thd Thread handler
6680 @param text Subquery's text
6681 @param text_length Length of 'text'
6682 @param text_offset Offset in bytes of 'text' in the original statement
6683 @param[out] node Produced PT_subquery object
6684
6685 @returns true if error
6686 */
6687 7161 static bool reparse_common_table_expr(THD *thd, const char *text,
6688 size_t text_length, uint text_offset,
6689 PT_subquery **node) {
6690
1/2
✓ Branch 0 taken 7161 times.
✗ Branch 1 not taken.
7161 Common_table_expr_parser_state parser_state;
6691
1/2
✓ Branch 0 taken 7161 times.
✗ Branch 1 not taken.
7161 parser_state.init(thd, text, text_length);
6692
6693 7161 Parser_state *old = thd->m_parser_state;
6694 7161 thd->m_parser_state = &parser_state;
6695
6696 /*
6697 Re-parsing a CTE creates Item_param-s and Item_sp_local-s which are
6698 special, as they do not exist in the original query: thus they should not
6699 exist from the points of view of logging.
6700 This is achieved like this:
6701 - for SP local vars: their pos_in_query is set to 0
6702 - for PS parameters: they are not added to LEX::param_list and thus not to
6703 Prepared_statement::param_array.
6704 They still need a value, which they get like this:
6705 - for SP local vars: through the ordinary look-up of SP local
6706 variables' values by name of the variable.
6707 - for PS parameters: first the first-parsed, 'non-special' Item-params,
6708 which are in param_array, get their value bound from user-supplied data,
6709 then they propagate their value to their 'special' clones (@see
6710 Item_param::m_clones).
6711 */
6712 7161 parser_state.m_lip.stmt_prepare_mode = old->m_lip.stmt_prepare_mode;
6713 7161 parser_state.m_lip.multi_statements = false; // A safety measure.
6714 7161 parser_state.m_lip.m_digest = nullptr;
6715
6716 // This is saved and restored by caller:
6717 7161 thd->lex->reparse_common_table_expr_at = text_offset;
6718
6719 /*
6720 As this function is called during parsing only, it can and should use the
6721 current Query_arena, character_set_client, etc.
6722 It intentionally uses THD::sql_parser() directly without the parse_sql()
6723 wrapper: because it's building a node of the statement currently being
6724 parsed at the upper call site.
6725 */
6726
1/2
✓ Branch 0 taken 7161 times.
✗ Branch 1 not taken.
7161 bool mysql_parse_status = thd->sql_parser();
6727 7161 thd->m_parser_state = old;
6728
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7161 times.
7161 if (mysql_parse_status) return true; /* purecov: inspected */
6729
6730 7161 *node = parser_state.result;
6731 7161 return false;
6732 7161 }
6733
6734 7855 bool PT_common_table_expr::make_subquery_node(THD *thd, PT_subquery **node) {
6735
2/2
✓ Branch 0 taken 481 times.
✓ Branch 1 taken 7374 times.
7855 if (m_postparse.references.size() >= 2) {
6736 // m_subq_node was already attached elsewhere, make new node:
6737 481 return reparse_common_table_expr(thd, m_subq_text.str, m_subq_text.length,
6738 481 m_subq_text_offset, node);
6739 }
6740 7374 *node = m_subq_node;
6741 7374 return false;
6742 }
6743
6744 /**
6745 Tries to match an identifier to the CTEs in scope; if matched, it
6746 modifies *table_name, *tl', and the matched with-list-element.
6747
6748 @param thd Thread handler
6749 @param[out] table_name Identifier
6750 @param[in,out] tl TABLE_LIST for the identifier
6751 @param pc Current parsing context, if available
6752 @param[out] found Is set to true if found.
6753
6754 @returns true if error (OOM).
6755 */
6756 4345059 bool Query_block::find_common_table_expr(THD *thd, Table_ident *table_name,
6757 TABLE_LIST *tl, Parse_context *pc,
6758 bool *found) {
6759 4345059 *found = false;
6760
2/2
✓ Branch 0 taken 3542651 times.
✓ Branch 1 taken 802408 times.
4345059 if (!pc) return false;
6761
6762 PT_with_clause *wc;
6763 802408 PT_common_table_expr *cte = nullptr;
6764 802408 Query_block *select = this;
6765 Query_expression *unit;
6766 do {
6767
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 988971 times.
988971 assert(select->first_execution);
6768 988971 unit = select->master_query_expression();
6769
2/2
✓ Branch 0 taken 972917 times.
✓ Branch 1 taken 16052 times.
988969 if (!(wc = unit->m_with_clause)) continue;
6770
3/4
✓ Branch 0 taken 16054 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 16044 times.
16052 if (wc->lookup(tl, &cte)) return true;
6771 /*
6772 If no match in the WITH clause of 'select', maybe this is a subquery, so
6773 look up in the outer query's WITH clause:
6774 */
6775
6/6
✓ Branch 0 taken 974433 times.
✓ Branch 1 taken 14528 times.
✓ Branch 2 taken 186520 times.
✓ Branch 3 taken 787911 times.
✓ Branch 4 taken 186563 times.
✓ Branch 5 taken 802396 times.
988961 } while (cte == nullptr && (select = unit->outer_query_block()));
6776
6777
2/2
✓ Branch 0 taken 787912 times.
✓ Branch 1 taken 14484 times.
802396 if (cte == nullptr) return false;
6778 14484 *found = true;
6779
6780 14484 const auto save_reparse_cte = thd->lex->reparse_common_table_expr_at;
6781 PT_subquery *node;
6782
2/2
✓ Branch 0 taken 6680 times.
✓ Branch 1 taken 7855 times.
14484 if (tl->is_recursive_reference()) {
6783 /*
6784 To pass the first steps of resolution, a recursive reference is here
6785 made to be a dummy derived table; after the temporary table is created
6786 based on the non-recursive members' types, the recursive reference is
6787 made to be a reference to the tmp table.
6788 */
6789 6680 LEX_CSTRING dummy_subq = {STRING_WITH_LEN("(select 0)")};
6790
2/4
✓ Branch 0 taken 6680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6680 times.
6680 if (reparse_common_table_expr(thd, dummy_subq.str, dummy_subq.length, 0,
6791 &node))
6792 return true; /* purecov: inspected */
6793
2/4
✓ Branch 0 taken 7855 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7855 times.
7855 } else if (cte->make_subquery_node(thd, &node))
6794 return true; /* purecov: inspected */
6795 // We imitate derived tables as much as possible.
6796
2/4
✓ Branch 0 taken 14535 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14535 times.
✗ Branch 3 not taken.
14535 assert(parsing_place == CTX_NONE && linkage != GLOBAL_OPTIONS_TYPE);
6797 14535 parsing_place = CTX_DERIVED;
6798 14535 node->m_is_derived_table = true;
6799 14535 auto wc_save = wc->enter_parsing_definition(tl);
6800
6801 /*
6802 The proper outer context for the CTE, is not the query block where the CTE
6803 reference is; neither is it the outer query block of this. It is the query
6804 block which immediately contains the query expression where the CTE
6805 definition is. Indeed, per the standard, evaluation of the CTE happens
6806 as first step of evaluation of the said query expression; so the CTE may
6807 not contain references into the said query expression.
6808 */
6809
3/4
✓ Branch 0 taken 213 times.
✓ Branch 1 taken 14322 times.
✓ Branch 2 taken 14535 times.
✗ Branch 3 not taken.
14748 thd->lex->push_context(unit->outer_query_block()
6810 213 ? &unit->outer_query_block()->context
6811 : nullptr);
6812
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14535 times.
14535 assert(thd->lex->will_contextualize);
6813
3/4
✓ Branch 0 taken 14535 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 14525 times.
14535 if (node->contextualize(pc)) return true;
6814
6815
1/2
✓ Branch 0 taken 14525 times.
✗ Branch 1 not taken.
14525 thd->lex->pop_context();
6816
6817 14525 wc->leave_parsing_definition(wc_save);
6818 14525 parsing_place = CTX_NONE;
6819 /*
6820 Prepared statement's parameters and SP local variables are spotted as
6821 'made during re-parsing' by node->contextualize(), which is why we
6822 ran that call _before_ restoring lex->reparse_common_table_expr_at.
6823 */
6824 14525 thd->lex->reparse_common_table_expr_at = save_reparse_cte;
6825 14525 tl->is_alias = true;
6826 Query_expression *node_query_expression =
6827 14525 node->value()->master_query_expression();
6828 14525 *table_name = Table_ident(node_query_expression);
6829
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14525 times.
14525 assert(table_name->is_derived_table());
6830 14525 tl->db = table_name->db.str;
6831 14525 tl->db_length = table_name->db.length;
6832 14525 return false;
6833 }
6834
6835 16054 bool PT_with_clause::lookup(TABLE_LIST *tl, PT_common_table_expr **found) {
6836 16054 *found = nullptr;
6837
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16054 times.
16054 assert(tl->query_block != nullptr);
6838 /*
6839 If right_bound!=NULL, it means we are currently parsing the
6840 definition of CTE 'right_bound' and this definition contains
6841 'tl'.
6842 */
6843 const Common_table_expr *right_bound =
6844
2/2
✓ Branch 0 taken 8189 times.
✓ Branch 1 taken 7865 times.
16054 m_most_inner_in_parsing ? m_most_inner_in_parsing->common_table_expr()
6845 16054 : nullptr;
6846 16054 bool in_self = false;
6847
2/2
✓ Branch 0 taken 16526 times.
✓ Branch 1 taken 141 times.
16667 for (auto el : m_list->elements()) {
6848 // Search for a CTE named like 'tl', in this list, from left to right.
6849
2/2
✓ Branch 0 taken 8058 times.
✓ Branch 1 taken 8468 times.
16526 if (el->is(right_bound)) {
6850 /*
6851 We meet right_bound.
6852 If not RECURSIVE:
6853 we must stop the search in this WITH clause;
6854 indeed right_bound must not reference itself or any CTE defined after it
6855 in the WITH list (forward references are forbidden, preventing any
6856 cycle).
6857 If RECURSIVE:
6858 If right_bound matches 'tl', it is a recursive reference.
6859 */
6860
2/2
✓ Branch 0 taken 1083 times.
✓ Branch 1 taken 6975 times.
22878 if (!m_recursive) break; // Prevent forward reference.
6861 6975 in_self = true; // Accept a recursive reference.
6862 }
6863 bool match;
6864
3/4
✓ Branch 0 taken 15443 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 15441 times.
15451 if (el->match_table_ref(tl, in_self, &match)) return true;
6865
2/2
✓ Branch 0 taken 898 times.
✓ Branch 1 taken 14543 times.
15441 if (!match) {
6866
2/2
✓ Branch 0 taken 285 times.
✓ Branch 1 taken 613 times.
898 if (in_self) break; // Prevent forward reference.
6867 613 continue;
6868 }
6869
4/4
✓ Branch 0 taken 6688 times.
✓ Branch 1 taken 7855 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 14535 times.
21231 if (in_self && tl->query_block->outer_query_block() !=
6870
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6680 times.
6688 m_most_inner_in_parsing->query_block) {
6871 /*
6872 SQL2011 says a recursive CTE cannot contain a subquery
6873 referencing the CTE, except if this subquery is a derived table
6874 like:
6875 WITH RECURSIVE qn AS (non-rec-SELECT UNION ALL
6876 SELECT * FROM (SELECT * FROM qn) AS dt)
6877 However, we don't allow this, as:
6878 - it simplifies detection and substitution correct recursive
6879 references (they're all on "level 0" of the UNION)
6880 - it's not limiting the user so much (in most cases, he can just
6881 merge his DT up manually, as the DT cannot contain aggregation).
6882 - Oracle bans it:
6883 with qn (a) as (
6884 select 123 from dual
6885 union all
6886 select 1+a from (select * from qn) where a<130) select * from qn
6887 ORA-32042: recursive WITH clause must reference itself directly in one
6888 of the UNION ALL branches.
6889
6890 The above if() works because, when we parse such example query, we
6891 first resolve the 'qn' reference in the top query, making it a derived
6892 table:
6893
6894 select * from (
6895 select 123 from dual
6896 union all
6897 select 1+a from (select * from qn) where a<130) qn(a);
6898 ^most_inner_in_parsing
6899 Then we contextualize that derived table (containing the union);
6900 when we contextualize the recursive query block of the union, the
6901 inner 'qn' is recognized as a recursive reference, and its
6902 query_block->outer_query_block() is _not_ the query_block of
6903 most_inner_in_parsing, which indicates that the inner 'qn' is placed
6904 too deep.
6905 */
6906 8 my_error(ER_CTE_RECURSIVE_REQUIRES_SINGLE_REFERENCE, MYF(0),
6907
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 el->name().str);
6908 8 return true;
6909 }
6910 14535 *found = el;
6911 14535 break;
6912 }
6913 16044 return false;
6914 }
6915
6916 15443 bool PT_common_table_expr::match_table_ref(TABLE_LIST *tl, bool in_self,
6917 bool *found) {
6918 15443 *found = false;
6919
2/2
✓ Branch 0 taken 14862 times.
✓ Branch 1 taken 581 times.
15443 if (tl->table_name_length == m_name.length &&
6920 /*
6921 memcmp() is fine even if lower_case_table_names==1, as CTE names
6922 have been lowercased in the ctor.
6923 */
6924
2/2
✓ Branch 0 taken 14545 times.
✓ Branch 1 taken 317 times.
14862 !memcmp(tl->table_name, m_name.str, m_name.length)) {
6925 14545 *found = true;
6926 // 'tl' is a reference to CTE 'el'.
6927
2/2
✓ Branch 0 taken 6690 times.
✓ Branch 1 taken 7855 times.
14545 if (in_self) {
6928 6690 m_postparse.recursive = true;
6929
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6688 times.
6690 if (tl->set_recursive_reference()) {
6930 2 my_error(ER_CTE_RECURSIVE_REQUIRES_SINGLE_REFERENCE, MYF(0),
6931 2 name().str);
6932 2 return true;
6933 }
6934 } else {
6935
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7855 times.
7855 if (m_postparse.references.push_back(tl))
6936 return true; /* purecov: inspected */
6937
2/2
✓ Branch 0 taken 6791 times.
✓ Branch 1 taken 1064 times.
7855 if (m_column_names.size()) tl->set_derived_column_names(&m_column_names);
6938 }
6939 14543 tl->set_common_table_expr(&m_postparse);
6940 }
6941 15441 return false;
6942 }
6943
6944 /**
6945 Add a table to list of used tables.
6946
6947 @param thd Current session.
6948 @param table_name Table to add
6949 @param alias alias for table (or null if no alias)
6950 @param table_options A set of the following bits:
6951 - TL_OPTION_UPDATING : Table will be updated
6952 - TL_OPTION_FORCE_INDEX : Force usage of index
6953 - TL_OPTION_ALIAS : an alias in multi table DELETE
6954 @param lock_type How table should be locked
6955 @param mdl_type Type of metadata lock to acquire on the table.
6956 @param index_hints_arg a list of index hints(FORCE/USE/IGNORE INDEX).
6957 @param partition_names List to carry partition names from PARTITION (...)
6958 clause in statement
6959 @param option Used by cache index
6960 @param pc Current parsing context, if available.
6961
6962 @return Pointer to TABLE_LIST element added to the total table list
6963 @retval
6964 0 Error
6965 */
6966
6967 11757058 TABLE_LIST *Query_block::add_table_to_list(
6968 THD *thd, Table_ident *table_name, const char *alias, ulong table_options,
6969 thr_lock_type lock_type, enum_mdl_type mdl_type,
6970 List<Index_hint> *index_hints_arg, List<String> *partition_names,
6971 LEX_STRING *option, Parse_context *pc) {
6972 11757058 TABLE_LIST *previous_table_ref =
6973 nullptr; /* The table preceding the current one. */
6974 11757058 LEX *lex = thd->lex;
6975
1/2
✓ Branch 0 taken 11758455 times.
✗ Branch 1 not taken.
11757058 DBUG_TRACE;
6976
6977
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11758455 times.
11758455 assert(table_name != nullptr);
6978 // A derived table has no table name, only an alias.
6979
6/6
✓ Branch 0 taken 11756410 times.
✓ Branch 1 taken 2045 times.
✓ Branch 2 taken 11527131 times.
✓ Branch 3 taken 229233 times.
✓ Branch 4 taken 11527316 times.
✓ Branch 5 taken 231093 times.
11758455 if (!(table_options & TL_OPTION_ALIAS) && !table_name->is_derived_table()) {
6980 Ident_name_check ident_check_status =
6981
1/2
✓ Branch 0 taken 11527372 times.
✗ Branch 1 not taken.
11527316 check_table_name(table_name->table.str, table_name->table.length);
6982
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 11527354 times.
11527372 if (ident_check_status == Ident_name_check::WRONG) {
6983
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name->table.str);
6984 18 return nullptr;
6985
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 11527345 times.
11527354 } else if (ident_check_status == Ident_name_check::TOO_LONG) {
6986
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 my_error(ER_TOO_LONG_IDENT, MYF(0), table_name->table.str);
6987 9 return nullptr;
6988 }
6989 }
6990 11758438 LEX_STRING db = to_lex_string(table_name->db);
6991
2/2
✓ Branch 0 taken 11520611 times.
✓ Branch 1 taken 7958 times.
23285916 if (!table_name->is_derived_table() && !table_name->is_table_function() &&
6992
6/6
✓ Branch 0 taken 11528508 times.
✓ Branch 1 taken 229056 times.
✓ Branch 2 taken 7173835 times.
✓ Branch 3 taken 4346776 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 11757649 times.
30459998 table_name->db.str &&
6993
3/4
✓ Branch 0 taken 7173865 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 7173859 times.
7173835 (check_and_convert_db_name(&db, false) != Ident_name_check::OK))
6994 6 return nullptr;
6995
6996
2/2
✓ Branch 0 taken 9043360 times.
✓ Branch 1 taken 2714289 times.
11757649 const char *alias_str = alias ? alias : table_name->table.str;
6997
2/2
✓ Branch 0 taken 9043506 times.
✓ Branch 1 taken 2714143 times.
11757649 if (!alias) /* Alias is case sensitive */
6998 {
6999
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9043506 times.
9043506 if (table_name->sel) {
7000 my_error(ER_DERIVED_MUST_HAVE_ALIAS, MYF(0));
7001 return nullptr;
7002 }
7003 9043425 if (!(alias_str =
7004
2/4
✓ Branch 0 taken 9043425 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9043425 times.
9043506 (char *)thd->memdup(alias_str, table_name->table.length + 1)))
7005 return nullptr;
7006 }
7007
7008
2/4
✓ Branch 0 taken 11757948 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11758467 times.
✗ Branch 3 not taken.
11757568 TABLE_LIST *ptr = new (thd->mem_root) TABLE_LIST;
7009
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11758467 times.
11758467 if (ptr == nullptr) return nullptr; /* purecov: inspected */
7010
7011
4/4
✓ Branch 0 taken 652789 times.
✓ Branch 1 taken 11105678 times.
✓ Branch 2 taken 651646 times.
✓ Branch 3 taken 1143 times.
11758467 if (lower_case_table_names && table_name->table.length)
7012
1/2
✓ Branch 0 taken 651646 times.
✗ Branch 1 not taken.
651646 table_name->table.length = my_casedn_str(
7013 files_charset_info, const_cast<char *>(table_name->table.str));
7014
7015 11758467 ptr->query_block = this;
7016 11758467 ptr->table_name = table_name->table.str;
7017 11758467 ptr->table_name_length = table_name->table.length;
7018 11758467 ptr->alias = alias_str;
7019 11758467 ptr->is_alias = alias != nullptr;
7020 11758467 ptr->table_function = table_name->table_function;
7021
2/2
✓ Branch 0 taken 7967 times.
✓ Branch 1 taken 11750500 times.
11758467 if (table_name->table_function) {
7022 7967 table_func_count++;
7023 7967 ptr->derived_key_list.clear();
7024 }
7025
7026
2/2
✓ Branch 0 taken 7411080 times.
✓ Branch 1 taken 4346973 times.
11758053 if (table_name->db.str) {
7027 7411080 ptr->is_fqtn = true;
7028 7411080 ptr->db = table_name->db.str;
7029 7411080 ptr->db_length = table_name->db.length;
7030 } else {
7031 // Check if the unqualified name could refer to a CTE. Don't do this for the
7032 // alias list of a multi-table DELETE statement (TL_OPTION_ALIAS), since
7033 // those are only references into the FROM list, and any CTEs referenced by
7034 // the aliases will be resolved when we later resolve the FROM list.
7035 4346973 bool found_cte = false;
7036
2/2
✓ Branch 0 taken 4345647 times.
✓ Branch 1 taken 1326 times.
4346973 if ((table_options & TL_OPTION_ALIAS) == 0) {
7037
3/4
✓ Branch 0 taken 4345115 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 4345095 times.
4345647 if (find_common_table_expr(thd, table_name, ptr, pc, &found_cte))
7038 68 return nullptr;
7039 }
7040
7/8
✓ Branch 0 taken 4332076 times.
✓ Branch 1 taken 14345 times.
✓ Branch 2 taken 4332008 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✓ Branch 5 taken 4331960 times.
✓ Branch 6 taken 48 times.
✓ Branch 7 taken 4346305 times.
4346421 if (!found_cte && lex->copy_db_to(&ptr->db, &ptr->db_length))
7041 48 return nullptr;
7042 }
7043
7044 11757385 ptr->set_tableno(0);
7045 11757365 ptr->set_lock({lock_type, THR_DEFAULT});
7046 11757721 ptr->updating = table_options & TL_OPTION_UPDATING;
7047 11757721 ptr->ignore_leaves = table_options & TL_OPTION_IGNORE_LEAVES;
7048 11757721 ptr->set_derived_query_expression(table_name->sel);
7049
7050
6/6
✓ Branch 0 taken 11513965 times.
✓ Branch 1 taken 243738 times.
✓ Branch 2 taken 11505978 times.
✓ Branch 3 taken 8259 times.
✓ Branch 4 taken 631735 times.
✓ Branch 5 taken 11126031 times.
23263316 if (!ptr->is_derived() && !ptr->is_table_function() &&
7051
3/4
✓ Branch 0 taken 11505769 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 631735 times.
✓ Branch 3 taken 10874034 times.
11505978 is_infoschema_db(ptr->db, ptr->db_length)) {
7052 631735 dd::info_schema::convert_table_name_case(
7053
1/2
✓ Branch 0 taken 631734 times.
✗ Branch 1 not taken.
631735 const_cast<char *>(ptr->db), const_cast<char *>(ptr->table_name));
7054
7055 631734 bool hidden_system_view = false;
7056
2/4
✓ Branch 0 taken 631734 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 631735 times.
✗ Branch 3 not taken.
631734 ptr->is_system_view = dd::get_dictionary()->is_system_view_name(
7057 ptr->db, ptr->table_name, &hidden_system_view);
7058
7059 ST_SCHEMA_TABLE *schema_table;
7060
2/2
✓ Branch 0 taken 16418 times.
✓ Branch 1 taken 615317 times.
631735 if (ptr->updating &&
7061 /* Special cases which are processed by commands itself */
7062
2/2
✓ Branch 0 taken 16416 times.
✓ Branch 1 taken 2 times.
16418 lex->sql_command != SQLCOM_CHECK &&
7063
2/2
✓ Branch 0 taken 16415 times.
✓ Branch 1 taken 1 times.
16416 lex->sql_command != SQLCOM_CHECKSUM &&
7064
4/4
✓ Branch 0 taken 16139 times.
✓ Branch 1 taken 276 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 16134 times.
16415 !(lex->sql_command == SQLCOM_CREATE_VIEW && ptr->is_system_view)) {
7065
1/2
✓ Branch 0 taken 281 times.
✗ Branch 1 not taken.
281 my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
7066
1/2
✓ Branch 0 taken 281 times.
✗ Branch 1 not taken.
281 thd->security_context()->priv_user().str,
7067
1/2
✓ Branch 0 taken 281 times.
✗ Branch 1 not taken.
281 thd->security_context()->priv_host().str,
7068 INFORMATION_SCHEMA_NAME.str);
7069 997 return nullptr;
7070 }
7071
2/2
✓ Branch 0 taken 383882 times.
✓ Branch 1 taken 247572 times.
631454 if (ptr->is_system_view) {
7072
2/2
✓ Branch 0 taken 362525 times.
✓ Branch 1 taken 21357 times.
383882 if (thd->lex->sql_command != SQLCOM_CREATE_VIEW) {
7073 /*
7074 Stop users from using hidden system views, unless
7075 it is used by SHOW commands.
7076 */
7077
5/6
✓ Branch 0 taken 362525 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1037 times.
✓ Branch 3 taken 361488 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 362524 times.
363562 if (thd->lex->query_block && hidden_system_view &&
7078
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1036 times.
1037 !(thd->lex->query_block->active_options() &
7079 OPTION_SELECT_FOR_SHOW)) {
7080
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_NO_SYSTEM_VIEW_ACCESS, MYF(0), ptr->table_name);
7081 1 return nullptr;
7082 }
7083
7084 /*
7085 Stop users from accessing I_S.FILES if they do not have
7086 PROCESS privilege.
7087 */
7088
4/4
✓ Branch 0 taken 26840 times.
✓ Branch 1 taken 335684 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 362519 times.
389364 if (!strcmp(ptr->table_name, "FILES") &&
7089
3/4
✓ Branch 0 taken 26840 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 26835 times.
26840 check_global_access(thd, PROCESS_ACL))
7090 5 return nullptr;
7091 }
7092 } else {
7093
1/2
✓ Branch 0 taken 247572 times.
✗ Branch 1 not taken.
247572 schema_table = find_schema_table(thd, ptr->table_name);
7094 /*
7095 Report an error
7096 if hidden schema table name is used in the statement other than
7097 SHOW statement OR
7098 if unknown schema table is used in the statement other than
7099 SHOW CREATE VIEW statement.
7100 Invalid view warning is reported for SHOW CREATE VIEW statement in
7101 the table open stage.
7102 */
7103 248282 if ((!schema_table &&
7104
2/4
✓ Branch 0 taken 710 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 710 times.
710 !(thd->query_plan.get_command() == SQLCOM_SHOW_CREATE &&
7105
5/10
✓ Branch 0 taken 710 times.
✓ Branch 1 taken 246862 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 246862 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 710 times.
✓ Branch 9 taken 246862 times.
495144 thd->query_plan.get_lex()->only_view)) ||
7106
2/2
✓ Branch 0 taken 197 times.
✓ Branch 1 taken 246665 times.
246862 (schema_table && schema_table->hidden &&
7107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 197 times.
197 (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0)) {
7108
1/2
✓ Branch 0 taken 710 times.
✗ Branch 1 not taken.
710 my_error(ER_UNKNOWN_TABLE, MYF(0), ptr->table_name,
7109 INFORMATION_SCHEMA_NAME.str);
7110 710 return nullptr;
7111 }
7112
7113
1/2
✓ Branch 0 taken 246862 times.
✗ Branch 1 not taken.
246862 if (schema_table) {
7114 246862 ptr->schema_table = schema_table;
7115 }
7116 }
7117 }
7118
7119 11756769 ptr->cacheable_table = true;
7120 11756769 ptr->index_hints = index_hints_arg;
7121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11756769 times.
11756769 ptr->option = option ? option->str : nullptr;
7122 /* check that used name is unique */
7123
2/2
✓ Branch 0 taken 11649971 times.
✓ Branch 1 taken 106798 times.
11756769 if (lock_type != TL_IGNORE) {
7124 11649971 TABLE_LIST *first_table = table_list.first;
7125
2/2
✓ Branch 0 taken 153664 times.
✓ Branch 1 taken 11496307 times.
11649971 if (lex->sql_command == SQLCOM_CREATE_VIEW)
7126
2/2
✓ Branch 0 taken 73514 times.
✓ Branch 1 taken 80150 times.
153664 first_table = first_table ? first_table->next_local : nullptr;
7127
2/2
✓ Branch 0 taken 16205616 times.
✓ Branch 1 taken 11649962 times.
27855578 for (TABLE_LIST *tables = first_table; tables;
7128 16205607 tables = tables->next_local) {
7129
5/6
✓ Branch 0 taken 16205615 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 43 times.
✓ Branch 3 taken 16205572 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 16205607 times.
16205659 if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
7130
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 35 times.
43 !strcmp(ptr->db, tables->db)) {
7131
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str); /* purecov: tested */
7132 8 return nullptr; /* purecov: tested */
7133 }
7134 }
7135 }
7136 /* Store the table reference preceding the current one. */
7137
2/2
✓ Branch 0 taken 2708352 times.
✓ Branch 1 taken 9048408 times.
11756760 if (table_list.elements > 0) {
7138 /*
7139 table_list.next points to the last inserted TABLE_LIST->next_local'
7140 element
7141 We don't use the offsetof() macro here to avoid warnings from gcc
7142 */
7143 2708352 previous_table_ref =
7144 (TABLE_LIST *)((char *)table_list.next -
7145 ((char *)&(ptr->next_local) - (char *)ptr));
7146 /*
7147 Set next_name_resolution_table of the previous table reference to point
7148 to the current table reference. In effect the list
7149 TABLE_LIST::next_name_resolution_table coincides with
7150 TABLE_LIST::next_local. Later this may be changed in
7151 store_top_level_join_columns() for NATURAL/USING joins.
7152 */
7153 2708352 previous_table_ref->next_name_resolution_table = ptr;
7154 }
7155
7156 /*
7157 Link the current table reference in a local list (list for current select).
7158 Notice that as a side effect here we set the next_local field of the
7159 previous table reference to 'ptr'. Here we also add one element to the
7160 list 'table_list'.
7161 */
7162 11756760 table_list.link_in_list(ptr, &ptr->next_local);
7163 11756140 ptr->next_name_resolution_table = nullptr;
7164 11756140 ptr->partition_names = partition_names;
7165 /* Link table in global list (all used tables) */
7166 11756140 lex->add_to_query_tables(ptr);
7167
7168 // Pure table aliases do not need to be locked:
7169
2/2
✓ Branch 0 taken 11754673 times.
✓ Branch 1 taken 1558 times.
11756231 if (!(table_options & TL_OPTION_ALIAS)) {
7170
1/2
✓ Branch 0 taken 11755859 times.
✗ Branch 1 not taken.
11754673 MDL_REQUEST_INIT(&ptr->mdl_request, MDL_key::TABLE, ptr->db,
7171 ptr->table_name, mdl_type, MDL_TRANSACTION);
7172 }
7173
2/2
✓ Branch 0 taken 243788 times.
✓ Branch 1 taken 11513641 times.
11757417 if (table_name->is_derived_table()) {
7174 243788 ptr->derived_key_list.clear();
7175 243788 derived_table_count++;
7176 }
7177
7178 // Check access to DD tables. We must allow CHECK and ALTER TABLE
7179 // for the DDSE tables, since this is expected by the upgrade
7180 // client. We must also allow DDL access for the initialize thread,
7181 // since this thread is creating the I_S views.
7182 // Note that at this point, the mdl request for CREATE TABLE is still
7183 // MDL_SHARED, so we must explicitly check for SQLCOM_CREATE_TABLE.
7184
1/2
✓ Branch 0 taken 11756598 times.
✗ Branch 1 not taken.
11757429 const dd::Dictionary *dictionary = dd::get_dictionary();
7185
3/4
✓ Branch 0 taken 11756747 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1915178 times.
✓ Branch 3 taken 9840665 times.
23512590 if (dictionary &&
7186
3/4
✓ Branch 0 taken 11755992 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1915178 times.
✓ Branch 3 taken 9840814 times.
11756381 !dictionary->is_dd_table_access_allowed(
7187
6/6
✓ Branch 0 taken 10718930 times.
✓ Branch 1 taken 1037844 times.
✓ Branch 2 taken 8804643 times.
✓ Branch 3 taken 1914292 times.
✓ Branch 4 taken 1956368 times.
✓ Branch 5 taken 6847877 times.
20560918 thd->is_dd_system_thread() || thd->is_initialize_system_thread() ||
7188 8804643 thd->is_server_upgrade_thread(),
7189 11756747 (ptr->mdl_request.is_ddl_or_lock_tables_lock_request() ||
7190
2/2
✓ Branch 0 taken 635222 times.
✓ Branch 1 taken 10555080 times.
11190302 (lex->sql_command == SQLCOM_CREATE_TABLE &&
7191
2/2
✓ Branch 0 taken 621274 times.
✓ Branch 1 taken 13948 times.
635222 ptr == lex->query_tables)) &&
7192
3/4
✓ Branch 0 taken 11190302 times.
✓ Branch 1 taken 566371 times.
✓ Branch 2 taken 1187698 times.
✗ Branch 3 not taken.
24134673 lex->sql_command != SQLCOM_CHECK &&
7193
2/2
✓ Branch 0 taken 1107102 times.
✓ Branch 1 taken 80596 times.
1187698 lex->sql_command != SQLCOM_ALTER_TABLE,
7194 ptr->db, ptr->db_length, ptr->table_name)) {
7195 // We must allow creation of the system views even for non-system
7196 // threads since this is expected by the mysql_upgrade utility.
7197 3830360 if (!(lex->sql_command == SQLCOM_CREATE_VIEW &&
7198
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
8 dd::get_dictionary()->is_system_view_name(
7199
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 lex->query_tables->db, lex->query_tables->table_name))
7200
5/8
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1915174 times.
✓ Branch 2 taken 1915178 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1915178 times.
✓ Branch 6 taken 1915178 times.
✗ Branch 7 not taken.
3830360 && !(dd::get_dictionary()->is_system_view_name(
7201
1/2
✓ Branch 0 taken 1915178 times.
✗ Branch 1 not taken.
1915178 lex->query_tables->db, lex->query_tables->table_name)
7202 && DBUG_EVALUATE_IF("skip_dd_table_access_check", true, false))
7203 ) {
7204
4/8
✓ Branch 0 taken 1915178 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1915178 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1915178 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1915178 times.
✗ Branch 7 not taken.
1915178 my_error(ER_NO_SYSTEM_TABLE_ACCESS, MYF(0),
7205
1/2
✓ Branch 0 taken 1915178 times.
✗ Branch 1 not taken.
1915178 ER_THD_NONCONST(thd, dictionary->table_type_error_code(
7206 ptr->db, ptr->table_name)),
7207 ptr->db, ptr->table_name);
7208 // Take error handler into account to see if we should return.
7209
3/4
✓ Branch 0 taken 1915303 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 138 times.
✓ Branch 3 taken 1915165 times.
1915178 if (thd->is_error()) return nullptr;
7210 }
7211 }
7212
7213 11755830 return ptr;
7214 11757074 }
7215
7216 /**
7217 Initialize a new table list for a nested join.
7218
7219 The function initializes a structure of the TABLE_LIST type
7220 for a nested join. It sets up its nested join list as empty.
7221 The created structure is added to the front of the current
7222 join list in the Query_block object. Then the function
7223 changes the current nest level for joins to refer to the newly
7224 created empty list after having saved the info on the old level
7225 in the initialized structure.
7226
7227 @param thd current thread
7228
7229 @retval
7230 0 if success
7231 @retval
7232 1 otherwise
7233 */
7234
7235 1783951 bool Query_block::init_nested_join(THD *thd) {
7236
1/2
✓ Branch 0 taken 1783951 times.
✗ Branch 1 not taken.
1783951 DBUG_TRACE;
7237
7238
1/2
✓ Branch 0 taken 1783951 times.
✗ Branch 1 not taken.
1783951 TABLE_LIST *const ptr = TABLE_LIST::new_nested_join(
7239 1783951 thd->mem_root, "(nested_join)", embedding, join_list, this);
7240
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1783951 times.
1783951 if (ptr == nullptr) return true;
7241
7242
1/2
✓ Branch 0 taken 1783951 times.
✗ Branch 1 not taken.
1783951 join_list->push_front(ptr);
7243 1783951 embedding = ptr;
7244 1783951 join_list = &ptr->nested_join->join_list;
7245
7246 1783951 return false;
7247 1783951 }
7248
7249 /**
7250 End a nested join table list.
7251
7252 The function returns to the previous join nest level.
7253 If the current level contains only one member, the function
7254 moves it one level up, eliminating the nest.
7255
7256 @return
7257 - Pointer to TABLE_LIST element added to the total table list, if success
7258 - 0, otherwise
7259 */
7260
7261 1782830 TABLE_LIST *Query_block::end_nested_join() {
7262 TABLE_LIST *ptr;
7263 NESTED_JOIN *nested_join;
7264
1/2
✓ Branch 0 taken 1782830 times.
✗ Branch 1 not taken.
1782830 DBUG_TRACE;
7265
7266
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1782830 times.
1782830 assert(embedding);
7267 1782830 ptr = embedding;
7268 1782830 join_list = ptr->join_list;
7269 1782830 embedding = ptr->embedding;
7270 1782830 nested_join = ptr->nested_join;
7271
1/2
✓ Branch 0 taken 1782830 times.
✗ Branch 1 not taken.
1782830 if (nested_join->join_list.size() == 1) {
7272
1/2
✓ Branch 0 taken 1782830 times.
✗ Branch 1 not taken.
1782830 TABLE_LIST *embedded = nested_join->join_list.front();
7273
1/2
✓ Branch 0 taken 1782830 times.
✗ Branch 1 not taken.
1782830 join_list->pop_front();
7274 1782830 embedded->join_list = join_list;
7275 1782830 embedded->embedding = embedding;
7276
1/2
✓ Branch 0 taken 1782830 times.
✗ Branch 1 not taken.
1782830 join_list->push_front(embedded);
7277 1782830 ptr = embedded;
7278 } else if (nested_join->join_list.empty()) {
7279 join_list->pop_front();
7280 ptr = nullptr; // return value
7281 }
7282 1782830 return ptr;
7283 1782830 }
7284
7285 /**
7286 Plumbing for nest_last_join, q.v.
7287 */
7288 1912128 TABLE_LIST *nest_join(THD *thd, Query_block *select, TABLE_LIST *embedding,
7289 mem_root_deque<TABLE_LIST *> *jlist, size_t table_cnt,
7290 const char *legend) {
7291
1/2
✓ Branch 0 taken 1912129 times.
✗ Branch 1 not taken.
1912128 DBUG_TRACE;
7292
7293
1/2
✓ Branch 0 taken 1912129 times.
✗ Branch 1 not taken.
1912129 TABLE_LIST *const ptr = TABLE_LIST::new_nested_join(thd->mem_root, legend,
7294 1912129 embedding, jlist, select);
7295
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1912129 times.
1912129 if (ptr == nullptr) return nullptr;
7296
7297 1912129 mem_root_deque<TABLE_LIST *> *const embedded_list =
7298 1912129 &ptr->nested_join->join_list;
7299
7300
2/2
✓ Branch 0 taken 3824372 times.
✓ Branch 1 taken 1912129 times.
5736501 for (uint i = 0; i < table_cnt; i++) {
7301
1/2
✓ Branch 0 taken 3824372 times.
✗ Branch 1 not taken.
3824372 TABLE_LIST *table = jlist->front();
7302
1/2
✓ Branch 0 taken 3824372 times.
✗ Branch 1 not taken.
3824372 jlist->pop_front();
7303 3824372 table->join_list = embedded_list;
7304 3824372 table->embedding = ptr;
7305
1/2
✓ Branch 0 taken 3824372 times.
✗ Branch 1 not taken.
3824372 embedded_list->push_back(table);
7306
2/2
✓ Branch 0 taken 14168 times.
✓ Branch 1 taken 3810204 times.
3824372 if (table->natural_join) ptr->is_natural_join = true;
7307 }
7308
1/2
✓ Branch 0 taken 1912129 times.
✗ Branch 1 not taken.
1912129 jlist->push_front(ptr);
7309
7310 1912129 return ptr;
7311 1912129 }
7312
7313 /**
7314 Nest last join operations.
7315
7316 The function nest last table_cnt join operations as if they were
7317 the components of a cross join operation.
7318
7319 @param thd current thread
7320 @param table_cnt 2 for regular joins: t1 JOIN t2.
7321 N for the MySQL join-like extension: (t1, t2, ... tN).
7322
7323 @return Pointer to TABLE_LIST element created for the new nested join
7324 @retval
7325 0 Error
7326 */
7327
7328 1912083 TABLE_LIST *Query_block::nest_last_join(THD *thd, size_t table_cnt) {
7329 1912083 return nest_join(thd, this, embedding, join_list, table_cnt,
7330 1912084 "(nest_last_join)");
7331 }
7332
7333 /**
7334 Add a table to the current join list.
7335
7336 The function puts a table in front of the current join list
7337 of Query_block object.
7338 Thus, joined tables are put into this list in the reverse order
7339 (the most outer join operation follows first).
7340
7341 @param table The table to add.
7342
7343 @returns false if success, true if error (OOM).
7344 */
7345
7346 4804449 bool Query_block::add_joined_table(TABLE_LIST *table) {
7347
1/2
✓ Branch 0 taken 4804461 times.
✗ Branch 1 not taken.
4804449 DBUG_TRACE;
7348
1/2
✓ Branch 0 taken 4804447 times.
✗ Branch 1 not taken.
4804461 join_list->push_front(table);
7349 4804447 table->join_list = join_list;
7350 4804447 table->embedding = embedding;
7351 4804462 return false;
7352 4804447 }
7353
7354 5030692 void Query_block::set_lock_for_table(const Lock_descriptor &descriptor,
7355 TABLE_LIST *table) {
7356 5030692 thr_lock_type lock_type = descriptor.type;
7357 5030692 bool for_update = lock_type >= TL_READ_NO_INSERT;
7358 5030692 enum_mdl_type mdl_type = mdl_type_for_dml(lock_type);
7359
1/2
✓ Branch 0 taken 5031329 times.
✗ Branch 1 not taken.
5031019 DBUG_TRACE;
7360
5/8
✓ Branch 0 taken 5031132 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5031189 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 5031176 times.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
5031329 DBUG_PRINT("enter", ("lock_type: %d for_update: %d", lock_type, for_update));
7361 5031189 table->set_lock(descriptor);
7362 5031197 table->updating = for_update;
7363 5031197 table->mdl_request.set_type(mdl_type);
7364 5030656 }
7365
7366 /**
7367 Set lock for all tables in current query block.
7368
7369 @param lock_type Lock to set for tables.
7370
7371 @note
7372 If the lock is a write lock, then tables->updating is set to true.
7373 This is to get tables_ok to know that the table is being updated by the
7374 query.
7375 Sets the type of metadata lock to request according to lock_type.
7376 */
7377 4964910 void Query_block::set_lock_for_tables(thr_lock_type lock_type) {
7378
1/2
✓ Branch 0 taken 4965892 times.
✗ Branch 1 not taken.
4964910 DBUG_TRACE;
7379
5/8
✓ Branch 0 taken 4965720 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4965752 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 4965739 times.
✓ Branch 6 taken 47 times.
✗ Branch 7 not taken.
4965892 DBUG_PRINT("enter", ("lock_type: %d for_update: %d", lock_type,
7380 lock_type >= TL_READ_NO_INSERT));
7381
2/2
✓ Branch 0 taken 5028988 times.
✓ Branch 1 taken 4966679 times.
9995667 for (TABLE_LIST *table = table_list.first; table; table = table->next_local)
7382
1/2
✓ Branch 0 taken 5029881 times.
✗ Branch 1 not taken.
5028988 set_lock_for_table({lock_type, THR_WAIT}, table);
7383 4966679 }
7384
7385 /**
7386 Create a fake Query_block for a unit.
7387
7388 The method create a fake Query_block object for a unit.
7389 This object is created for any union construct containing a union
7390 operation and also for any single select union construct of the form
7391 @verbatim
7392 (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ...
7393 @endverbatim
7394 or of the form
7395 @verbatim
7396 (SELECT ... ORDER BY LIMIT n) ORDER BY ...
7397 @endverbatim
7398
7399 @param thd thread handle
7400
7401 @note
7402 The object is used to retrieve rows from the temporary table
7403 where the result on the union is obtained.
7404
7405 @retval
7406 1 on failure to create the object
7407 @retval
7408 0 on success
7409 */
7410
7411 21792 bool Query_expression::add_fake_query_block(THD *thd) {
7412 21792 Query_block *first_qb = first_query_block();
7413
1/2
✓ Branch 0 taken 21792 times.
✗ Branch 1 not taken.
21792 DBUG_TRACE;
7414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21792 times.
21792 assert(!fake_query_block);
7415
7416
2/4
✓ Branch 0 taken 21792 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 21792 times.
21792 if (!(fake_query_block = thd->lex->new_empty_query_block()))
7417 return true; /* purecov: inspected */
7418
1/2
✓ Branch 0 taken 21792 times.
✗ Branch 1 not taken.
21792 fake_query_block->include_standalone(this, &fake_query_block);
7419 21792 fake_query_block->select_number = INT_MAX;
7420 21792 fake_query_block->linkage = GLOBAL_OPTIONS_TYPE;
7421 21792 fake_query_block->select_limit = nullptr;
7422
7423
1/2
✓ Branch 0 taken 21792 times.
✗ Branch 1 not taken.
21792 fake_query_block->set_context(first_qb->context.outer_context);
7424
7425 /* allow item list resolving in fake select for ORDER BY */
7426 21792 fake_query_block->context.resolve_in_select_list = true;
7427
7428
1/2
✓ Branch 0 taken 21792 times.
✗ Branch 1 not taken.
21792 if (!is_union()) {
7429 /*
7430 This works only for
7431 (SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m],
7432 (SELECT ... LIMIT n) ORDER BY order_list [LIMIT m]
7433 just before the parser starts processing order_list
7434 */
7435 21792 fake_query_block->no_table_names_allowed = true;
7436 }
7437
1/2
✓ Branch 0 taken 21792 times.
✗ Branch 1 not taken.
21792 thd->lex->pop_context();
7438 21792 return false;
7439 21792 }
7440
7441 /**
7442 Push a new name resolution context for a JOIN ... ON clause to the
7443 context stack of a query block.
7444
7445 Create a new name resolution context for a JOIN ... ON clause,
7446 set the first and last leaves of the list of table references
7447 to be used for name resolution, and push the newly created
7448 context to the stack of contexts of the query.
7449
7450 @param pc current parse context
7451 @param left_op left operand of the JOIN
7452 @param right_op right operand of the JOIN
7453
7454 @retval
7455 false if all is OK
7456 @retval
7457 true if a memory allocation error occurred
7458 */
7459
7460 1885295 bool push_new_name_resolution_context(Parse_context *pc, TABLE_LIST *left_op,
7461 TABLE_LIST *right_op) {
7462 1885295 THD *thd = pc->thd;
7463 Name_resolution_context *on_context;
7464
3/6
✓ Branch 0 taken 1885295 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1885295 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1885295 times.
1885295 if (!(on_context = new (thd->mem_root) Name_resolution_context)) return true;
7465 1885295 on_context->init();
7466 1885295 on_context->first_name_resolution_table =
7467 1885295 left_op->first_leaf_for_name_resolution();
7468 1885295 on_context->last_name_resolution_table =
7469 1885295 right_op->last_leaf_for_name_resolution();
7470 1885295 on_context->query_block = pc->select;
7471 // Other tables in FROM clause of this JOIN are not visible:
7472 1885295 on_context->outer_context = thd->lex->current_context()->outer_context;
7473 1885295 on_context->next_context = pc->select->first_context;
7474 1885295 pc->select->first_context = on_context;
7475
7476 1885295 return thd->lex->push_context(on_context);
7477 }
7478
7479 /**
7480 Add an ON condition to the second operand of a JOIN ... ON.
7481
7482 Add an ON condition to the right operand of a JOIN ... ON clause.
7483
7484 @param b the second operand of a JOIN ... ON
7485 @param expr the condition to be added to the ON clause
7486 */
7487
7488 1900192 void add_join_on(TABLE_LIST *b, Item *expr) {
7489
1/2
✓ Branch 0 taken 1900192 times.
✗ Branch 1 not taken.
1900192 if (expr) {
7490 1900192 b->set_join_cond_optim((Item *)1); // m_join_cond_optim is not ready
7491
2/2
✓ Branch 0 taken 1898235 times.
✓ Branch 1 taken 1957 times.
1900192 if (!b->join_cond())
7492 1898235 b->set_join_cond(expr);
7493 else {
7494 /*
7495 If called from the parser, this happens if you have both a
7496 right and left join. If called later, it happens if we add more
7497 than one condition to the ON clause.
7498 */
7499
2/4
✓ Branch 0 taken 1957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1957 times.
✗ Branch 3 not taken.
1957 b->set_join_cond(new Item_cond_and(b->join_cond(), expr));
7500 }
7501 1900192 b->join_cond()->apply_is_true();
7502 }
7503 1900192 }
7504
7505 10 const CHARSET_INFO *get_bin_collation(const CHARSET_INFO *cs) {
7506 const CHARSET_INFO *ret =
7507
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 get_charset_by_csname(cs->csname, MY_CS_BINSORT, MYF(0));
7508
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if (ret) return ret;
7509
7510 char tmp[65];
7511 strmake(strmake(tmp, cs->csname, sizeof(tmp) - 4), STRING_WITH_LEN("_bin"));
7512 my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
7513 return nullptr;
7514 }
7515
7516 /**
7517 kill on thread.
7518
7519 @param thd Thread class
7520 @param id Thread id
7521 @param only_kill_query Should it kill the query or the connection
7522
7523 @note
7524 This is written such that we have a short lock on LOCK_thd_list
7525 */
7526
7527 2601 static uint kill_one_thread(THD *thd, my_thread_id id, bool only_kill_query) {
7528 2601 uint error = ER_NO_SUCH_THREAD;
7529 2601 Find_thd_with_id find_thd_with_id(id, false);
7530
7531
1/2
✓ Branch 0 taken 2601 times.
✗ Branch 1 not taken.
2601 DBUG_TRACE;
7532
3/8
✓ Branch 0 taken 2601 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2601 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2601 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2601 DBUG_PRINT("enter", ("id=%u only_kill=%d", id, only_kill_query));
7533
1/2
✓ Branch 0 taken 2601 times.
✗ Branch 1 not taken.
2601 THD_ptr tmp = Global_THD_manager::get_instance()->find_thd(&find_thd_with_id);
7534 2601 Security_context *sctx = thd->security_context();
7535
2/2
✓ Branch 0 taken 2572 times.
✓ Branch 1 taken 29 times.
2601 if (tmp) {
7536 /*
7537 If we're SUPER, we can KILL anything, including system-threads.
7538 No further checks.
7539
7540 KILLer: thd->m_security_ctx->user could in theory be NULL while
7541 we're still in "unauthenticated" state. This is a theoretical
7542 case (the code suggests this could happen, so we play it safe).
7543
7544 KILLee: tmp->m_security_ctx->user will be NULL for system threads.
7545 We need to check so Jane Random User doesn't crash the server
7546 when trying to kill a) system threads or b) unauthenticated users'
7547 threads (Bug#43748).
7548
7549 If user of both killer and killee are non-NULL, proceed with
7550 slayage if both are string-equal.
7551 */
7552
7553
1/2
✓ Branch 0 taken 2572 times.
✗ Branch 1 not taken.
2572 const bool is_utility_connection = acl_is_utility_user(
7554
2/4
✓ Branch 0 taken 2572 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2572 times.
✗ Branch 3 not taken.
2572 tmp->m_security_ctx->user().str, tmp->m_security_ctx->host().str,
7555
1/2
✓ Branch 0 taken 2572 times.
✗ Branch 1 not taken.
2572 tmp->m_security_ctx->ip().str);
7556 #ifdef WITH_WSREP
7557
3/4
✓ Branch 0 taken 2572 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 2567 times.
2572 if (wsrep_thd_is_in_to_isolation(tmp.get(), false)) {
7558 /* There is nothing special about the use of ER_QUERY_INTERRUPTED,
7559 I just needed a different error code from ER_KILL_DENIED_ERROR.
7560
7561 See sql_kill() to see the other half of the error processing.
7562 */
7563 5 error = ER_QUERY_INTERRUPTED;
7564
4/10
✓ Branch 0 taken 2567 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2567 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2551 times.
✓ Branch 5 taken 16 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
5134 } else if ((((sctx->check_access(SUPER_ACL) ||
7565
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
44 sctx->has_global_grant(STRING_WITH_LEN("CONNECTION_ADMIN"))
7566
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 15 times.
44 .first) &&
7567
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2551 times.
2552 !is_utility_connection) ||
7568
3/4
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 10 times.
16 sctx->user_matches(tmp->security_context())) &&
7569
9/12
✓ Branch 0 taken 2567 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 2523 times.
✓ Branch 4 taken 2557 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2555 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 2551 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 2567 times.
✗ Branch 11 not taken.
7701 !wsrep_thd_is_BF(tmp.get(), true) && !tmp->wsrep_applier) {
7570 #else
7571 if (((sctx->check_access(SUPER_ACL) ||
7572 sctx->has_global_grant(STRING_WITH_LEN("CONNECTION_ADMIN")).first) &&
7573 !is_utility_connection) ||
7574 sctx->user_matches(tmp->security_context())) {
7575 #endif /* WITH_WSREP */
7576 /*
7577 Process the kill:
7578 if thread is not already undergoing any kill connection.
7579 Killer must have SYSTEM_USER privilege iff killee has the same privilege
7580 privilege
7581 */
7582
1/2
✓ Branch 0 taken 2551 times.
✗ Branch 1 not taken.
2551 if (tmp->killed != THD::KILL_CONNECTION) {
7583
8/10
✓ Branch 0 taken 2551 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2414 times.
✓ Branch 3 taken 137 times.
✓ Branch 4 taken 2414 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 18 times.
✓ Branch 7 taken 2396 times.
✓ Branch 8 taken 18 times.
✓ Branch 9 taken 2533 times.
2551 if (tmp->is_system_user() && !thd->is_system_user()) {
7584 18 error = ER_KILL_DENIED_ERROR;
7585 } else {
7586 #ifdef WITH_WSREP
7587
3/4
✓ Branch 0 taken 2507 times.
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 2507 times.
✗ Branch 3 not taken.
2533 DEBUG_SYNC(thd, "before_awake_no_mutex");
7588
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2533 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2533 times.
2533 if (tmp->wsrep_aborter && tmp->wsrep_aborter != thd->thread_id()) {
7589 /* victim is in hit list already, bail out */
7590 WSREP_DEBUG("victim has wsrep aborter: %u, skipping awake()",
7591 tmp->wsrep_aborter);
7592 error = 0;
7593 } else {
7594
1/24
✗ Branch 0 not taken.
✓ Branch 1 taken 2533 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
2533 WSREP_DEBUG("kill_one_thread victim: %u aborter %u kill query %d",
7595 id, tmp->wsrep_aborter, only_kill_query);
7596 #endif /* WITH_WSREP */
7597
3/4
✓ Branch 0 taken 199 times.
✓ Branch 1 taken 2334 times.
✓ Branch 2 taken 2533 times.
✗ Branch 3 not taken.
2533 tmp->awake(only_kill_query ? THD::KILL_QUERY
7598 : THD::KILL_CONNECTION);
7599 2533 error = 0;
7600 #ifdef WITH_WSREP
7601 }
7602 #endif /* WITH_WSREP */
7603 }
7604 } else
7605 error = 0;
7606 } else
7607 16 error = ER_KILL_DENIED_ERROR;
7608 }
7609
3/4
✓ Branch 0 taken 2562 times.
✓ Branch 1 taken 39 times.
✓ Branch 2 taken 2562 times.
✗ Branch 3 not taken.
2601 DEBUG_SYNC(thd, "kill_thd_end");
7610
3/8
✓ Branch 0 taken 2601 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2601 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2601 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2601 DBUG_PRINT("exit", ("%d", error));
7611 2601 return error;
7612 2601 }
7613
7614 #ifdef WITH_WSREP
7615 165 static void wsrep_prepare_for_autocommit_retry(THD *thd, const char *rawbuf,
7616 uint length,
7617 Parser_state *parser_state) {
7618 165 thd->clear_error();
7619 165 thd->wsrep_aborter = 0;
7620 165 close_thread_tables(thd);
7621 /* Ensure the gtid is resetted on query retry so retry attempt operates
7622 with same flow as normal attempt waiting for sync_wait if needed. */
7623 165 thd->wsrep_cs().reset_sync_wait_gtid();
7624 165 thd->wsrep_retry_counter++; // grow
7625 165 wsrep_copy_query(thd);
7626 165 thd->set_time();
7627 165 parser_state->reset(rawbuf, length);
7628
7629 /* PSI end */
7630 165 MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
7631 165 thd->m_statement_psi = NULL;
7632 165 thd->m_digest = NULL;
7633
7634 /* SHOW PROFILE end */
7635 #if defined(ENABLED_PROFILING)
7636 165 thd->profiling->finish_current_query();
7637 #endif
7638
7639 /* SHOW PROFILE begin */
7640 #if defined(ENABLED_PROFILING)
7641 165 thd->profiling->start_new_query("continuing");
7642 165 thd->profiling->set_query_source(rawbuf, length);
7643 #endif
7644
7645 /* Performance Schema Interface instrumentation, begin */
7646 165 thd->m_statement_psi = MYSQL_REFINE_STATEMENT(
7647 thd->m_statement_psi, com_statement_info[thd->get_command()].m_key);
7648 165 MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, thd->query().str,
7649 thd->query().length);
7650
7651
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 165 times.
165 assert(thd->wsrep_trx().active() == false);
7652 165 thd->wsrep_cs().reset_error();
7653 165 thd->set_query_id(next_query_id());
7654 165 }
7655
7656 274 static bool wsrep_should_retry_in_autocommit(const THD *thd) {
7657 /*
7658 We are here could mean that the query resulted in a cluster-wide
7659 conflict and had to be aborted. While it happened, it is possible that
7660 the client may have already received partial data from server and may
7661 have been waiting for the OK/EOF packet (usually sent by
7662 THD::send_statement_status() in dispatch_command()) to report it to the
7663 user.
7664
7665 When retry is performed in such a case, the server shall start sending
7666 result and field metadata once again and this would cause the client
7667 program to receive unexpected metadata information in place of an
7668 OK/EOF packet and thus causes the client to error out with Malformed
7669 packet error.
7670
7671 So, we avoid retries for such queries that return result set to client,
7672 but cannot be run in TOI and can be killed by a TOI.
7673
7674 As of now, we only do this check for CHECK TABLE and SELECT, and if the
7675 same symptom is found for other commands, then please add it to the
7676 below list.
7677 */
7678
3/3
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 268 times.
274 switch (thd->lex->sql_command) {
7679 1 case SQLCOM_CHECK:
7680 case SQLCOM_SELECT:
7681 1 return false;
7682 5 case SQLCOM_ALTER_TABLE: {
7683 5 return (thd->lex->alter_info->flags & Alter_info::ALTER_ADMIN_PARTITION
7684 ? false
7685 5 : true);
7686 }
7687 268 default:
7688 268 return true;
7689 }
7690 }
7691
7692 162902 static bool wsrep_dispatch_sql_command(THD *thd, const char *rawbuf,
7693 uint length, Parser_state *parser_state,
7694 bool update_userstat) {
7695
1/2
✓ Branch 0 taken 162903 times.
✗ Branch 1 not taken.
162902 DBUG_TRACE;
7696
2/2
✓ Branch 0 taken 151735 times.
✓ Branch 1 taken 11167 times.
314640 bool is_autocommit = !thd->in_multi_stmt_transaction_mode() &&
7697
2/4
✓ Branch 0 taken 151737 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 151737 times.
✗ Branch 3 not taken.
314639 wsrep_read_only_option(thd, thd->lex->query_tables);
7698 bool retry_autocommit;
7699
7700
2/2
✓ Branch 0 taken 165 times.
✓ Branch 1 taken 162901 times.
163066 do {
7701 163069 retry_autocommit = false;
7702
1/2
✓ Branch 0 taken 163066 times.
✗ Branch 1 not taken.
163069 dispatch_sql_command(thd, parser_state, update_userstat);
7703
7704 /*
7705 Convert all ER_QUERY_INTERRUPTED errors to ER_LOCK_DEADLOCK
7706 if the transaction was BF aborted. This can happen when the
7707 transaction is being BF aborted via thd->awake() while it is
7708 still executing.
7709
7710 Note that this must be done before wsrep_after_statement() call
7711 since it clears the transaction for autocommit queries.
7712 */
7713
2/2
✓ Branch 0 taken 7317 times.
✓ Branch 1 taken 192 times.
170575 if (((thd->get_stmt_da()->is_error() &&
7714 7509 thd->get_stmt_da()->mysql_errno() == ER_QUERY_INTERRUPTED) ||
7715
8/8
✓ Branch 0 taken 7509 times.
✓ Branch 1 taken 155557 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 162864 times.
✓ Branch 4 taken 191 times.
✓ Branch 5 taken 11 times.
✓ Branch 6 taken 191 times.
✓ Branch 7 taken 162875 times.
170585 !thd->get_stmt_da()->is_set()) &&
7716 202 thd->wsrep_trx().bf_aborted()) {
7717
1/26
✗ Branch 0 not taken.
✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
191 WSREP_DEBUG("overriding error: %d with DEADLOCK",
7718 (thd->get_stmt_da()->is_error())
7719 ? thd->get_stmt_da()->mysql_errno()
7720 : 0);
7721
7722 191 thd->killed = THD::NOT_KILLED;
7723
1/2
✓ Branch 0 taken 191 times.
✗ Branch 1 not taken.
191 wsrep_override_error(thd, ER_LOCK_DEADLOCK);
7724 }
7725
7726
7/8
✓ Branch 0 taken 163066 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 334 times.
✓ Branch 3 taken 162732 times.
✓ Branch 4 taken 274 times.
✓ Branch 5 taken 60 times.
✓ Branch 6 taken 274 times.
✓ Branch 7 taken 162792 times.
163066 if (wsrep_after_statement(thd) && is_autocommit) {
7727
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 thd->reset_for_next_command();
7728 274 thd->killed = THD::NOT_KILLED;
7729
5/6
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 272 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 165 times.
✓ Branch 5 taken 109 times.
546 if (is_autocommit && wsrep_should_retry_in_autocommit(thd) &&
7730
2/2
✓ Branch 0 taken 165 times.
✓ Branch 1 taken 107 times.
272 thd->wsrep_retry_counter < thd->variables.wsrep_retry_autocommit) {
7731
5/8
✓ Branch 0 taken 165 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 65 times.
✓ Branch 3 taken 100 times.
✓ Branch 4 taken 65 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 65 times.
165 DBUG_EXECUTE_IF("sync.wsrep_retry_autocommit", {
7732 const char act[] =
7733 "now "
7734 "SIGNAL wsrep_retry_autocommit_reached "
7735 "WAIT_FOR wsrep_retry_autocommit_continue";
7736 assert(!debug_sync_set_action(thd, STRING_WITH_LEN(act)));
7737 });
7738
1/40
✗ Branch 0 not taken.
✓ Branch 1 taken 165 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
165 WSREP_DEBUG("wsrep retrying AC query: %lu %s",
7739 thd->wsrep_retry_counter, WSREP_QUERY(thd));
7740
1/2
✓ Branch 0 taken 165 times.
✗ Branch 1 not taken.
165 wsrep_prepare_for_autocommit_retry(thd, rawbuf, length, parser_state);
7741 // if (thd->lex->explain) delete_explain_query(thd->lex);
7742 165 retry_autocommit = true;
7743 } else {
7744
1/42
✗ Branch 0 not taken.
✓ Branch 1 taken 109 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
109 WSREP_DEBUG("%s, thd: %u is_AC: %d, retry: %lu - %lu SQL: %s",
7745 wsrep_thd_transaction_state_str(thd), thd->thread_id(),
7746 is_autocommit, thd->wsrep_retry_counter,
7747 thd->variables.wsrep_retry_autocommit, WSREP_QUERY(thd));
7748
1/2
✓ Branch 0 taken 108 times.
✗ Branch 1 not taken.
109 my_error(ER_LOCK_DEADLOCK, MYF(0));
7749 108 thd->killed = THD::NOT_KILLED;
7750 109 thd->wsrep_retry_counter = 0; // reset
7751 }
7752 } else {
7753 162792 thd->wsrep_retry_counter = 0;
7754 }
7755 } while (retry_autocommit);
7756
7757
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 162852 times.
162901 if (thd->wsrep_retry_query) {
7758
1/28
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
49 WSREP_DEBUG(
7759 "releasing retry_query: "
7760 "conf %s sent %d kill %d errno %d SQL %s",
7761 wsrep_thd_transaction_state_str(thd), thd->get_stmt_da()->is_sent(),
7762 thd->killed.load(),
7763 thd->get_stmt_da()->is_error() ? thd->get_stmt_da()->mysql_errno() : 0,
7764 thd->wsrep_retry_query);
7765
1/2
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
49 my_free(thd->wsrep_retry_query);
7766 49 thd->wsrep_retry_query = NULL;
7767 49 thd->wsrep_retry_query_len = 0;
7768 49 thd->wsrep_retry_command = COM_CONNECT;
7769 }
7770
7771 #if 0
7772 /* Keep this code here for easy validation.
7773 If there is multi-stmt transaction then transaction locks are present at this
7774 point. */
7775 assert(!thd->mdl_context.has_stmt_locks());
7776 assert(!thd->mdl_context.has_transactional_locks() || thd->in_multi_stmt_transaction_mode());
7777 assert(!thd->mdl_context.has_explicit_locks());
7778 #endif
7779
7780 162900 return false;
7781 162901 }
7782 #endif /* WITH_WSREP */
7783
7784 /*
7785 kills a thread and sends response
7786
7787 SYNOPSIS
7788 sql_kill()
7789 thd Thread class
7790 id Thread id
7791 only_kill_query Should it kill the query or the connection
7792 */
7793
7794 2601 static void sql_kill(THD *thd, my_thread_id id, bool only_kill_query) {
7795 uint error;
7796
2/2
✓ Branch 0 taken 2533 times.
✓ Branch 1 taken 68 times.
2601 if (!(error = kill_one_thread(thd, id, only_kill_query))) {
7797
2/2
✓ Branch 0 taken 2491 times.
✓ Branch 1 taken 42 times.
2533 if (!thd->killed) my_ok(thd);
7798 } else
7799 #ifdef WITH_WSREP
7800
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 63 times.
68 if (error == ER_QUERY_INTERRUPTED) {
7801 5 my_printf_error(ER_KILL_DENIED_ERROR,
7802 "The query is in TOI/NBO and cannot be killed", MYF(0));
7803 } else
7804 #endif /* WITH_WSREP */
7805 63 my_error(error, MYF(0), id);
7806 2601 }
7807
7808 /**
7809 This class implements callback function used by killall_non_super_threads
7810 to kill all threads that do not have the SUPER privilege
7811 */
7812
7813 class Kill_non_super_conn : public Do_THD_Impl {
7814 private:
7815 /* THD of connected client. */
7816 THD *m_client_thd;
7817 bool m_is_client_regular_user;
7818
7819 public:
7820 35 Kill_non_super_conn(THD *thd) : m_client_thd(thd) {
7821
8/18
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 30 times.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 5 times.
✓ Branch 10 taken 35 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 35 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
35 assert(m_client_thd->security_context()->check_access(SUPER_ACL) ||
7822 m_client_thd->security_context()
7823 ->has_global_grant(STRING_WITH_LEN("SYSTEM_VARIABLES_ADMIN"))
7824 .first);
7825
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
35 m_is_client_regular_user = !m_client_thd->is_system_user();
7826 35 }
7827
7828 464 void operator()(THD *thd_to_kill) override {
7829 464 mysql_mutex_lock(&thd_to_kill->LOCK_thd_data);
7830
7831 464 Security_context *sctx = thd_to_kill->security_context();
7832
7833 const bool is_utility_user =
7834 464 acl_is_utility_user(sctx->user().str, sctx->host().str, sctx->ip().str);
7835
7836 /* Kill only if non-privileged thread and non slave thread.
7837 If an account has not yet been assigned to the security context of the
7838 thread we cannot tell if the account is super user or not. In this case
7839 we cannot kill that thread. In offline mode, after the account is
7840 assigned to this thread and it turns out it is not privileged user
7841 thread, the authentication for this thread will fail and the thread will
7842 be terminated.
7843 Additionally, client with SYSTEM_VARIABLES_ADMIN but not SYSTEM_USER
7844 privilege is not allowed to kill threads having SYSTEM_USER,
7845 but not CONNECTION_ADMIN privilege.
7846 */
7847 const bool has_higher_privilege =
7848
4/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 451 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 5 times.
464 m_is_client_regular_user && thd_to_kill->is_system_user();
7849
1/2
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
716 if (!thd_to_kill->is_connection_admin() &&
7850 252 thd_to_kill->killed != THD::KILL_CONNECTION &&
7851
10/10
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 212 times.
✓ Branch 2 taken 251 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 249 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 248 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 248 times.
✓ Branch 9 taken 216 times.
716 !thd_to_kill->slave_thread && !has_higher_privilege && !is_utility_user)
7852 248 thd_to_kill->awake(THD::KILL_CONNECTION);
7853
7854 464 mysql_mutex_unlock(&thd_to_kill->LOCK_thd_data);
7855 464 }
7856 };
7857
7858 /*
7859 kills all the threads that do not have the
7860 SUPER privilege.
7861
7862 SYNOPSIS
7863 killall_non_super_threads()
7864 thd Thread class
7865 */
7866
7867 35 void killall_non_super_threads(THD *thd) {
7868
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
35 Kill_non_super_conn kill_non_super_conn(thd);
7869 35 Global_THD_manager *thd_manager = Global_THD_manager::get_instance();
7870
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
35 thd_manager->do_for_all_thd(&kill_non_super_conn);
7871 35 }
7872
7873 /**
7874 prepares the index and data directory path.
7875
7876 @param thd Thread handle
7877 @param data_file_name Pathname for data directory
7878 @param index_file_name Pathname for index directory
7879 @param table_name Table name to be appended to the pathname
7880 specified
7881
7882 @return false success
7883 @return true An error occurred
7884 */
7885
7886 618791 bool prepare_index_and_data_dir_path(THD *thd, const char **data_file_name,
7887 const char **index_file_name,
7888 const char *table_name) {
7889 int ret_val;
7890 const char *file_name;
7891 const char *directory_type;
7892
7893 /*
7894 If a data directory path is passed, check if the path exists and append
7895 table_name to it.
7896 */
7897
3/4
✓ Branch 0 taken 618792 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 618784 times.
1237582 if (data_file_name &&
7898
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 618785 times.
618792 (ret_val = append_file_to_dir(thd, data_file_name, table_name))) {
7899 6 file_name = *data_file_name;
7900 6 directory_type = "DATA DIRECTORY";
7901 6 goto err;
7902 }
7903
7904 /*
7905 If an index directory path is passed, check if the path exists and append
7906 table_name to it.
7907 */
7908
3/4
✓ Branch 0 taken 618786 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 618781 times.
1237570 if (index_file_name &&
7909
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 618783 times.
618786 (ret_val = append_file_to_dir(thd, index_file_name, table_name))) {
7910 3 file_name = *index_file_name;
7911 3 directory_type = "INDEX DIRECTORY";
7912 3 goto err;
7913 }
7914
7915 618781 return false;
7916 9 err:
7917
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8 times.
9 if (ret_val == ER_PATH_LENGTH)
7918 1 my_error(ER_PATH_LENGTH, MYF(0), directory_type);
7919
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
9 if (ret_val == ER_WRONG_VALUE)
7920 8 my_error(ER_WRONG_VALUE, MYF(0), "path", file_name);
7921 9 return true;
7922 }
7923
7924 /** If pointer is not a null pointer, append filename to it. */
7925
7926 1237577 int append_file_to_dir(THD *thd, const char **filename_ptr,
7927 const char *table_name) {
7928 char tbbuff[FN_REFLEN];
7929 char buff[FN_REFLEN];
7930 char *ptr;
7931 char *end;
7932
7933
2/2
✓ Branch 0 taken 1237401 times.
✓ Branch 1 taken 176 times.
1237577 if (!*filename_ptr) return 0; // nothing to do
7934
7935 /* Convert tablename to filename charset so that "/" gets converted
7936 appropriately */
7937
1/2
✓ Branch 0 taken 176 times.
✗ Branch 1 not taken.
176 size_t tab_len = tablename_to_filename(table_name, tbbuff, sizeof(tbbuff));
7938
7939 /* Check that the filename is not too long and it's a hard path */
7940
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 175 times.
176 if (strlen(*filename_ptr) + tab_len >= FN_REFLEN - 1) return ER_PATH_LENGTH;
7941
7942
3/4
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 167 times.
175 if (!test_if_hard_path(*filename_ptr)) return ER_WRONG_VALUE;
7943
7944 /* Fix is using unix filename format on dos */
7945 167 my_stpcpy(buff, *filename_ptr);
7946
1/2
✓ Branch 0 taken 167 times.
✗ Branch 1 not taken.
167 end = convert_dirname(buff, *filename_ptr, NullS);
7947
7948
1/2
✓ Branch 0 taken 167 times.
✗ Branch 1 not taken.
167 ptr = (char *)thd->alloc((size_t)(end - buff) + tab_len + 1);
7949
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 167 times.
167 if (ptr == nullptr) return ER_OUTOFMEMORY; // End of memory
7950 167 *filename_ptr = ptr;
7951
1/2
✓ Branch 0 taken 167 times.
✗ Branch 1 not taken.
167 strxmov(ptr, buff, tbbuff, NullS);
7952 167 return 0;
7953 }
7954
7955 9574301 Comp_creator *comp_eq_creator(bool invert) {
7956
2/2
✓ Branch 0 taken 314 times.
✓ Branch 1 taken 9573987 times.
9574301 return invert ? (Comp_creator *)&ne_creator : (Comp_creator *)&eq_creator;
7957 }
7958
7959 3068 Comp_creator *comp_equal_creator(bool invert [[maybe_unused]]) {
7960
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3068 times.
3068 assert(!invert); // Function never called with true.
7961 3068 return &equal_creator;
7962 }
7963
7964 31921 Comp_creator *comp_ge_creator(bool invert) {
7965
2/2
✓ Branch 0 taken 156 times.
✓ Branch 1 taken 31765 times.
31921 return invert ? (Comp_creator *)&lt_creator : (Comp_creator *)&ge_creator;
7966 }
7967
7968 203341 Comp_creator *comp_gt_creator(bool invert) {
7969
2/2
✓ Branch 0 taken 321 times.
✓ Branch 1 taken 203020 times.
203341 return invert ? (Comp_creator *)&le_creator : (Comp_creator *)&gt_creator;
7970 }
7971
7972 499354 Comp_creator *comp_le_creator(bool invert) {
7973
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 499250 times.
499354 return invert ? (Comp_creator *)&gt_creator : (Comp_creator *)&le_creator;
7974 }
7975
7976 64251 Comp_creator *comp_lt_creator(bool invert) {
7977
2/2
✓ Branch 0 taken 222 times.
✓ Branch 1 taken 64029 times.
64251 return invert ? (Comp_creator *)&ge_creator : (Comp_creator *)&lt_creator;
7978 }
7979
7980 1990495 Comp_creator *comp_ne_creator(bool invert) {
7981
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1990495 times.
1990495 return invert ? (Comp_creator *)&eq_creator : (Comp_creator *)&ne_creator;
7982 }
7983
7984 /**
7985 Construct ALL/ANY/SOME subquery Item.
7986
7987 @param left_expr pointer to left expression
7988 @param cmp compare function creator
7989 @param all true if we create ALL subquery
7990 @param query_block pointer on parsed subquery structure
7991
7992 @return
7993 constructed Item (or 0 if out of memory)
7994 */
7995 2889 Item *all_any_subquery_creator(Item *left_expr,
7996 chooser_compare_func_creator cmp, bool all,
7997 Query_block *query_block) {
7998
4/4
✓ Branch 0 taken 721 times.
✓ Branch 1 taken 2168 times.
✓ Branch 2 taken 416 times.
✓ Branch 3 taken 305 times.
2889 if ((cmp == &comp_eq_creator) && !all) // = ANY <=> IN
7999
2/4
✓ Branch 0 taken 416 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 416 times.
✗ Branch 3 not taken.
416 return new Item_in_subselect(left_expr, query_block);
8000
4/4
✓ Branch 0 taken 344 times.
✓ Branch 1 taken 2129 times.
✓ Branch 2 taken 191 times.
✓ Branch 3 taken 153 times.
2473 if ((cmp == &comp_ne_creator) && all) // <> ALL <=> NOT IN
8001 {
8002
2/4
✓ Branch 0 taken 191 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 191 times.
✗ Branch 3 not taken.
191 Item *i = new Item_in_subselect(left_expr, query_block);
8003
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 191 times.
191 if (i == nullptr) return nullptr;
8004 191 Item *neg_i = i->truth_transformer(nullptr, Item::BOOL_NEGATED);
8005
1/2
✓ Branch 0 taken 191 times.
✗ Branch 1 not taken.
191 if (neg_i != nullptr) return neg_i;
8006 return new Item_func_not(i);
8007 }
8008 Item_allany_subselect *it =
8009
2/4
✓ Branch 0 taken 2282 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2282 times.
✗ Branch 3 not taken.
2282 new Item_allany_subselect(left_expr, cmp, query_block, all);
8010
4/6
✓ Branch 0 taken 1099 times.
✓ Branch 1 taken 1183 times.
✓ Branch 2 taken 1099 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1099 times.
✗ Branch 5 not taken.
2282 if (all) return it->upper_item = new Item_func_not_all(it); /* ALL */
8011
8012
2/4
✓ Branch 0 taken 1183 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1183 times.
✗ Branch 3 not taken.
1183 return it->upper_item = new Item_func_nop_all(it); /* ANY/SOME */
8013 }
8014
8015 /**
8016 Set proper open mode and table type for element representing target table
8017 of CREATE TABLE statement, also adjust statement table list if necessary.
8018 */
8019
8020 620843 void create_table_set_open_action_and_adjust_tables(LEX *lex) {
8021 620843 TABLE_LIST *create_table = lex->query_tables;
8022
8023
2/2
✓ Branch 0 taken 54511 times.
✓ Branch 1 taken 566332 times.
620843 if (lex->create_info->options & HA_LEX_CREATE_TMP_TABLE)
8024 54511 create_table->open_type = OT_TEMPORARY_ONLY;
8025 else
8026 566332 create_table->open_type = OT_BASE_ONLY;
8027
8028
2/2
✓ Branch 0 taken 609913 times.
✓ Branch 1 taken 10930 times.
620843 if (lex->query_block->fields.empty()) {
8029 /*
8030 Avoid opening and locking target table for ordinary CREATE TABLE
8031 or CREATE TABLE LIKE for write (unlike in CREATE ... SELECT we
8032 won't do any insertions in it anyway). Not doing this causes
8033 problems when running CREATE TABLE IF NOT EXISTS for already
8034 existing log table.
8035 */
8036 609913 create_table->set_lock({TL_READ, THR_DEFAULT});
8037 }
8038 620843 }
8039
8040 /**
8041 Set the specified definer to the default value, which is the
8042 current user in the thread.
8043
8044 @param[in] thd thread handler
8045 @param[out] definer definer
8046 */
8047
8048 33050 void get_default_definer(THD *thd, LEX_USER *definer) {
8049 33050 const Security_context *sctx = thd->security_context();
8050
8051 33050 definer->user.str = sctx->priv_user().str;
8052 33050 definer->user.length = strlen(definer->user.str);
8053
8054 33050 definer->host.str = sctx->priv_host().str;
8055 33050 definer->host.length = strlen(definer->host.str);
8056
8057 33050 definer->first_factor_auth_info.plugin = EMPTY_CSTR;
8058 33050 definer->first_factor_auth_info.auth = NULL_CSTR;
8059 33050 definer->current_auth = NULL_CSTR;
8060 33050 definer->first_factor_auth_info.uses_identified_with_clause = false;
8061 33050 definer->first_factor_auth_info.uses_identified_by_clause = false;
8062 33050 definer->first_factor_auth_info.uses_authentication_string_clause = false;
8063 33050 definer->uses_replace_clause = false;
8064 33050 definer->retain_current_password = false;
8065 33050 definer->discard_old_password = false;
8066 33050 definer->alter_status.update_password_expired_column = false;
8067 33050 definer->alter_status.use_default_password_lifetime = true;
8068 33050 definer->alter_status.expire_after_days = 0;
8069 33050 definer->alter_status.update_account_locked_column = false;
8070 33050 definer->alter_status.account_locked = false;
8071 33050 definer->alter_status.update_password_require_current =
8072 Lex_acl_attrib_udyn::DEFAULT;
8073 33050 definer->first_factor_auth_info.has_password_generator = false;
8074 33050 definer->alter_status.failed_login_attempts = 0;
8075 33050 definer->alter_status.password_lock_time = 0;
8076 33050 definer->alter_status.update_failed_login_attempts = false;
8077 33050 definer->alter_status.update_password_lock_time = false;
8078 33050 }
8079
8080 /**
8081 Create default definer for the specified THD.
8082
8083 @param[in] thd thread handler
8084
8085 @return
8086 - On success, return a valid pointer to the created and initialized
8087 LEX_USER, which contains definer information.
8088 - On error, return 0.
8089 */
8090
8091 31738 LEX_USER *create_default_definer(THD *thd) {
8092 LEX_USER *definer;
8093
8094
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31738 times.
31738 if (!(definer = (LEX_USER *)LEX_USER::alloc(thd))) return nullptr;
8095
8096 31738 thd->get_definer(definer);
8097
8098 31738 return definer;
8099 }
8100
8101 /**
8102 Returns information about user or current user.
8103
8104 @param[in] thd thread handler
8105 @param[in] user user
8106
8107 @return
8108 - On success, return a valid pointer to initialized
8109 LEX_USER, which contains user information.
8110 - On error, return 0.
8111 */
8112 #ifdef WITH_WSREP
8113 483851 LEX_USER *get_current_user(THD *thd, LEX_USER *user, bool for_rewrite) {
8114 #else
8115 LEX_USER *get_current_user(THD *thd, LEX_USER *user) {
8116 #endif
8117
3/4
✓ Branch 0 taken 483851 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 310 times.
✓ Branch 3 taken 483541 times.
483851 if (!user || !user->user.str) // current_user
8118 {
8119 310 LEX_USER *default_definer = create_default_definer(thd);
8120
1/2
✓ Branch 0 taken 312 times.
✗ Branch 1 not taken.
312 if (default_definer) {
8121 #ifdef WITH_WSREP
8122
7/10
✓ Branch 0 taken 312 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 298 times.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 11 times.
✓ Branch 9 taken 3 times.
312 if (WSREP(thd) && !for_rewrite &&
8123
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 (thd->lex->sql_command == SQLCOM_ALTER_USER ||
8124
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 times.
11 thd->lex->sql_command == SQLCOM_CREATE_USER ||
8125
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
10 thd->lex->sql_command == SQLCOM_DROP_USER ||
8126
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2 times.
9 thd->lex->sql_command == SQLCOM_RENAME_USER ||
8127
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
7 thd->lex->sql_command == SQLCOM_REVOKE ||
8128
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 thd->lex->sql_command == SQLCOM_REVOKE_ALL ||
8129
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
5 thd->lex->sql_command == SQLCOM_GRANT)) {
8130
13/28
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 8 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 8 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 8 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 8 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 8 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
8 WSREP_ERROR(
8131 "Percona XtraDB Cluster doesn't allow use of"
8132 " CURRENT_USER/USER function for USER operation"
8133 " while operating in cluster mode");
8134 char message[1024];
8135 8 sprintf(message,
8136 "Percona XtraDB Cluster doesn't allow use of"
8137 " CURRENT_USER/USER function for USER operation"
8138 " while operating in cluster mode");
8139
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 my_message(ER_UNKNOWN_ERROR, message, MYF(0));
8140 8 return 0;
8141 }
8142 #endif /* WITH_WSREP */
8143
8144 /*
8145 Inherit parser semantics from the statement in which the user parameter
8146 was used.
8147 This is needed because a LEX_USER is both used as a component in an
8148 AST and as a specifier for a particular user in the ACL subsystem.
8149 */
8150 default_definer->first_factor_auth_info
8151 304 .uses_authentication_string_clause =
8152 304 user->first_factor_auth_info.uses_authentication_string_clause;
8153 304 default_definer->first_factor_auth_info.uses_identified_by_clause =
8154 304 user->first_factor_auth_info.uses_identified_by_clause;
8155 304 default_definer->first_factor_auth_info.uses_identified_with_clause =
8156 304 user->first_factor_auth_info.uses_identified_with_clause;
8157 304 default_definer->uses_replace_clause = user->uses_replace_clause;
8158 304 default_definer->current_auth.str = user->current_auth.str;
8159 304 default_definer->current_auth.length = user->current_auth.length;
8160 304 default_definer->retain_current_password = user->retain_current_password;
8161 304 default_definer->discard_old_password = user->discard_old_password;
8162 304 default_definer->first_factor_auth_info.plugin =
8163 user->first_factor_auth_info.plugin;
8164 304 default_definer->first_factor_auth_info.auth =
8165 user->first_factor_auth_info.auth;
8166 304 default_definer->alter_status = user->alter_status;
8167 304 default_definer->first_factor_auth_info.has_password_generator =
8168 304 user->first_factor_auth_info.has_password_generator;
8169 304 return default_definer;
8170 }
8171 }
8172
8173 483541 return user;
8174 }
8175
8176 /**
8177 Check that byte length of a string does not exceed some limit.
8178
8179 @param str string to be checked
8180 @param err_msg error message to be displayed if the string is too long
8181 @param max_byte_length max length
8182
8183 @retval
8184 false the passed string is not longer than max_length
8185 @retval
8186 true the passed string is longer than max_length
8187
8188 NOTE
8189 The function is not used in existing code but can be useful later?
8190 */
8191
8192 350458 static bool check_string_byte_length(const LEX_CSTRING &str,
8193 const char *err_msg,
8194 size_t max_byte_length) {
8195
2/2
✓ Branch 0 taken 350437 times.
✓ Branch 1 taken 21 times.
350458 if (str.length <= max_byte_length) return false;
8196
8197 21 my_error(ER_WRONG_STRING_LENGTH, MYF(0), str.str, err_msg, max_byte_length);
8198
8199 21 return true;
8200 }
8201
8202 /*
8203 Check that char length of a string does not exceed some limit.
8204
8205 SYNOPSIS
8206 check_string_char_length()
8207 str string to be checked
8208 err_msg error message to be displayed if the string is too long
8209 max_char_length max length in symbols
8210 cs string charset
8211
8212 RETURN
8213 false the passed string is not longer than max_char_length
8214 true the passed string is longer than max_char_length
8215 */
8216
8217 14761480 bool check_string_char_length(const LEX_CSTRING &str, const char *err_msg,
8218 size_t max_char_length, const CHARSET_INFO *cs,
8219 bool no_error) {
8220 int well_formed_error;
8221
1/2
✓ Branch 0 taken 14761492 times.
✗ Branch 1 not taken.
14761480 size_t res = cs->cset->well_formed_len(cs, str.str, str.str + str.length,
8222 max_char_length, &well_formed_error);
8223
8224
4/4
✓ Branch 0 taken 14761491 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 14761381 times.
✓ Branch 3 taken 110 times.
14761492 if (!well_formed_error && str.length == res) return false;
8225
8226
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 62 times.
111 if (!no_error) {
8227
1/2
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
49 ErrConvString err(str.str, str.length, cs);
8228
1/2
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
49 my_error(ER_WRONG_STRING_LENGTH, MYF(0), err.ptr(), err_msg,
8229 max_char_length);
8230 }
8231 111 return true;
8232 }
8233
8234 /*
8235 Check if path does not contain mysql data home directory
8236 SYNOPSIS
8237 test_if_data_home_dir()
8238 dir directory
8239 conv_home_dir converted data home directory
8240 home_dir_len converted data home directory length
8241
8242 RETURN VALUES
8243 0 ok
8244 1 error
8245 */
8246 19413 int test_if_data_home_dir(const char *dir) {
8247 char path[FN_REFLEN];
8248 size_t dir_len;
8249
1/2
✓ Branch 0 taken 19413 times.
✗ Branch 1 not taken.
19413 DBUG_TRACE;
8250
8251
2/2
✓ Branch 0 taken 18590 times.
✓ Branch 1 taken 823 times.
19413 if (!dir) return 0;
8252
8253
1/2
✓ Branch 0 taken 823 times.
✗ Branch 1 not taken.
823 (void)fn_format(path, dir, "", "",
8254 (MY_RETURN_REAL_PATH | MY_RESOLVE_SYMLINKS));
8255 823 dir_len = strlen(path);
8256
2/2
✓ Branch 0 taken 370 times.
✓ Branch 1 taken 453 times.
823 if (mysql_unpacked_real_data_home_len <= dir_len) {
8257
2/2
✓ Branch 0 taken 321 times.
✓ Branch 1 taken 49 times.
370 if (dir_len > mysql_unpacked_real_data_home_len &&
8258
2/2
✓ Branch 0 taken 303 times.
✓ Branch 1 taken 18 times.
321 path[mysql_unpacked_real_data_home_len] != FN_LIBCHAR)
8259 303 return 0;
8260
8261
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67 times.
67 if (lower_case_file_system) {
8262 if (!my_strnncoll(default_charset_info, (const uchar *)path,
8263 mysql_unpacked_real_data_home_len,
8264 (const uchar *)mysql_unpacked_real_data_home,
8265 mysql_unpacked_real_data_home_len))
8266 return 1;
8267
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 44 times.
67 } else if (!memcmp(path, mysql_unpacked_real_data_home,
8268 mysql_unpacked_real_data_home_len))
8269 23 return 1;
8270 }
8271 497 return 0;
8272 19413 }
8273
8274 /**
8275 Check that host name string is valid.
8276
8277 @param[in] str string to be checked
8278
8279 @return Operation status
8280 @retval false host name is ok
8281 @retval true host name string is longer than max_length or
8282 has invalid symbols
8283 */
8284
8285 350459 bool check_host_name(const LEX_CSTRING &str) {
8286 350459 const char *name = str.str;
8287 350459 const char *end = str.str + str.length;
8288
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 350437 times.
350459 if (check_string_byte_length(str, ER_THD(current_thd, ER_HOSTNAME),
8289 HOSTNAME_LENGTH))
8290 21 return true;
8291
8292
2/2
✓ Branch 0 taken 3153631 times.
✓ Branch 1 taken 350435 times.
3504066 while (name != end) {
8293
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3153629 times.
3153631 if (*name == '@') {
8294 2 my_printf_error(ER_UNKNOWN_ERROR,
8295 "Malformed hostname (illegal symbol: '%c')", MYF(0),
8296 2 *name);
8297 2 return true;
8298 }
8299 3153629 name++;
8300 }
8301 350435 return false;
8302 }
8303
8304 class Parser_oom_handler : public Internal_error_handler {
8305 public:
8306 17229914 Parser_oom_handler() : m_has_errors(false), m_is_mem_error(false) {}
8307 3356789 bool handle_condition(THD *thd, uint sql_errno, const char *,
8308 Sql_condition::enum_severity_level *level,
8309 const char *) override {
8310
2/2
✓ Branch 0 taken 1922994 times.
✓ Branch 1 taken 1433795 times.
3356789 if (*level == Sql_condition::SL_ERROR) {
8311 1922994 m_has_errors = true;
8312 /* Out of memory error is reported only once. Return as handled */
8313
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1922992 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
1922994 if (m_is_mem_error &&
8314
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 (sql_errno == EE_CAPACITY_EXCEEDED || sql_errno == EE_OUTOFMEMORY))
8315 return true;
8316
3/4
✓ Branch 0 taken 1922993 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1922993 times.
1922994 if (sql_errno == EE_CAPACITY_EXCEEDED || sql_errno == EE_OUTOFMEMORY) {
8317 1 m_is_mem_error = true;
8318
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (sql_errno == EE_CAPACITY_EXCEEDED)
8319 1 my_error(ER_CAPACITY_EXCEEDED, MYF(0),
8320 1 static_cast<ulonglong>(thd->variables.parser_max_mem_size),
8321 "parser_max_mem_size",
8322 ER_THD(thd, ER_CAPACITY_EXCEEDED_IN_PARSER));
8323 else
8324 my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
8325 1 return true;
8326 }
8327 }
8328 3356788 return false;
8329 }
8330
8331 private:
8332 bool m_has_errors;
8333 bool m_is_mem_error;
8334 };
8335
8336 /**
8337 Transform an SQL statement into an AST that is ready for resolving, using the
8338 supplied parser state and object creation context.
8339
8340 This is a wrapper() for THD::sql_parser() and should generally be used for AST
8341 construction.
8342
8343 The function may optionally generate a query digest, invoke this function as
8344 follows:
8345
8346
8347 @verbatim
8348 THD *thd = ...;
8349 const char *query_text = ...;
8350 uint query_length = ...;
8351 Object_creation_ctx *ctx = ...;
8352 bool rc;
8353
8354 Parser_state parser_state;
8355 if (parser_state.init(thd, query_text, query_length)
8356 {
8357 ... handle error
8358 }
8359
8360 parser_state.m_input.m_has_digest= true;
8361 parser_state.m_input.m_compute_digest= true;
8362
8363 rc= parse_sql(the, &parser_state, ctx);
8364 if (! rc)
8365 {
8366 unsigned char md5[MD5_HASH_SIZE];
8367 char digest_text[1024];
8368 bool truncated;
8369 const sql_digest_storage *digest= & thd->m_digest->m_digest_storage;
8370
8371 compute_digest_md5(digest, & md5[0]);
8372 compute_digest_text(digest, & digest_text[0], sizeof(digest_text), &
8373 truncated);
8374 }
8375 @endverbatim
8376
8377 @param thd Thread context.
8378 @param parser_state Parser state.
8379 @param creation_ctx Object creation context.
8380
8381 @return Error status.
8382 @retval false on success.
8383 @retval true on parsing error.
8384 */
8385
8386 17229922 bool parse_sql(THD *thd, Parser_state *parser_state,
8387 Object_creation_ctx *creation_ctx) {
8388
1/2
✓ Branch 0 taken 17231547 times.
✗ Branch 1 not taken.
17229922 DBUG_TRACE;
8389 bool ret_value;
8390
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17231547 times.
17231547 assert(thd->m_parser_state == nullptr);
8391 // TODO fix to allow parsing gcol exprs after main query.
8392 // assert(thd->lex->m_sql_cmd == NULL);
8393
8394 /* Backup creation context. */
8395
8396 17231547 Object_creation_ctx *backup_ctx = nullptr;
8397
8398
3/4
✓ Branch 0 taken 741420 times.
✓ Branch 1 taken 16490127 times.
✓ Branch 2 taken 741420 times.
✗ Branch 3 not taken.
17231547 if (creation_ctx) backup_ctx = creation_ctx->set_n_backup(thd);
8399
8400 /* Set parser state. */
8401
8402 17231547 thd->m_parser_state = parser_state;
8403
8404 17231547 parser_state->m_digest_psi = nullptr;
8405 17231547 parser_state->m_lip.m_digest = nullptr;
8406
8407 /*
8408 Partial parsers (GRAMMAR_SELECTOR_*) are not supposed to compute digests.
8409 */
8410
3/4
✓ Branch 0 taken 236332 times.
✓ Branch 1 taken 16993993 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 236332 times.
17231547 assert(!parser_state->m_lip.is_partial_parser() ||
8411 !parser_state->m_input.m_has_digest);
8412
8413 /*
8414 Only consider statements that are supposed to have a digest,
8415 like top level queries.
8416 */
8417
2/2
✓ Branch 0 taken 11723126 times.
✓ Branch 1 taken 5507199 times.
17230325 if (parser_state->m_input.m_has_digest) {
8418 /*
8419 For these statements,
8420 see if the digest computation is required.
8421 */
8422
2/2
✓ Branch 0 taken 11723100 times.
✓ Branch 1 taken 26 times.
11723126 if (thd->m_digest != nullptr) {
8423 /* Start Digest */
8424
1/2
✓ Branch 0 taken 11723433 times.
✗ Branch 1 not taken.
11723100 parser_state->m_digest_psi = MYSQL_DIGEST_START(thd->m_statement_psi);
8425
8426
2/2
✓ Branch 0 taken 76 times.
✓ Branch 1 taken 11723357 times.
11723433 if (parser_state->m_input.m_compute_digest ||
8427
1/2
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
76 (parser_state->m_digest_psi != nullptr)) {
8428 /*
8429 If either:
8430 - the caller wants to compute a digest
8431 - the performance schema wants to compute a digest
8432 set the digest listener in the lexer.
8433 */
8434 11723433 parser_state->m_lip.m_digest = thd->m_digest;
8435 11723366 parser_state->m_lip.m_digest->m_digest_storage.m_charset_number =
8436 11723433 thd->charset()->number;
8437 }
8438 }
8439 }
8440
8441 /* Parse the query. */
8442
8443 /*
8444 Use a temporary DA while parsing. We don't know until after parsing
8445 whether the current command is a diagnostic statement, in which case
8446 we'll need to have the previous DA around to answer questions about it.
8447 */
8448 17230591 Diagnostics_area *parser_da = thd->get_parser_da();
8449 17231040 Diagnostics_area *da = thd->get_stmt_da();
8450
8451 17231134 Parser_oom_handler poomh;
8452 // Note that we may be called recursively here, on INFORMATION_SCHEMA queries.
8453
8454 17230407 thd->mem_root->set_max_capacity(thd->variables.parser_max_mem_size);
8455 17229882 thd->mem_root->set_error_for_capacity_exceeded(true);
8456
1/2
✓ Branch 0 taken 17230034 times.
✗ Branch 1 not taken.
17229718 thd->push_internal_handler(&poomh);
8457
8458
1/2
✓ Branch 0 taken 17230815 times.
✗ Branch 1 not taken.
17230034 thd->push_diagnostics_area(parser_da, false);
8459
8460
1/2
✓ Branch 0 taken 17229936 times.
✗ Branch 1 not taken.
17230815 bool mysql_parse_status = thd->sql_parser();
8461
8462
1/2
✓ Branch 0 taken 17229383 times.
✗ Branch 1 not taken.
17229936 thd->pop_internal_handler();
8463 17229383 thd->mem_root->set_max_capacity(0);
8464 17229810 thd->mem_root->set_error_for_capacity_exceeded(false);
8465 /*
8466 Unwind diagnostics area.
8467
8468 If any issues occurred during parsing, they will become
8469 the sole conditions for the current statement.
8470
8471 Otherwise, if we have a diagnostic statement on our hands,
8472 we'll preserve the previous diagnostics area here so we
8473 can answer questions about it. This specifically means
8474 that repeatedly asking about a DA won't clear it.
8475
8476 Otherwise, it's a regular command with no issues during
8477 parsing, so we'll just clear the DA in preparation for
8478 the processing of this command.
8479 */
8480
8481
2/2
✓ Branch 0 taken 547408 times.
✓ Branch 1 taken 16683189 times.
17229976 if (parser_da->current_statement_cond_count() != 0) {
8482 /*
8483 Error/warning during parsing: top DA should contain parse error(s)! Any
8484 pre-existing conditions will be replaced. The exception is diagnostics
8485 statements, in which case we wish to keep the errors so they can be sent
8486 to the client.
8487 */
8488
2/2
✓ Branch 0 taken 547396 times.
✓ Branch 1 taken 12 times.
547408 if (thd->lex->sql_command != SQLCOM_SHOW_WARNS &&
8489
2/2
✓ Branch 0 taken 547394 times.
✓ Branch 1 taken 2 times.
547396 thd->lex->sql_command != SQLCOM_GET_DIAGNOSTICS)
8490
1/2
✓ Branch 0 taken 547394 times.
✗ Branch 1 not taken.
547394 da->reset_condition_info(thd);
8491
8492 /*
8493 We need to put any errors in the DA as well as the condition list.
8494 */
8495
6/6
✓ Branch 0 taken 7906 times.
✓ Branch 1 taken 539502 times.
✓ Branch 2 taken 7866 times.
✓ Branch 3 taken 40 times.
✓ Branch 4 taken 7866 times.
✓ Branch 5 taken 539542 times.
547408 if (parser_da->is_error() && !da->is_error()) {
8496
1/2
✓ Branch 0 taken 7866 times.
✗ Branch 1 not taken.
7866 da->set_error_status(parser_da->mysql_errno(), parser_da->message_text(),
8497 parser_da->returned_sqlstate());
8498 }
8499
8500
1/2
✓ Branch 0 taken 547408 times.
✗ Branch 1 not taken.
547408 da->copy_sql_conditions_from_da(thd, parser_da);
8501
8502
1/2
✓ Branch 0 taken 547408 times.
✗ Branch 1 not taken.
547408 parser_da->reset_diagnostics_area();
8503
1/2
✓ Branch 0 taken 547408 times.
✗ Branch 1 not taken.
547408 parser_da->reset_condition_info(thd);
8504
8505 /*
8506 Do not clear the condition list when starting execution as it
8507 now contains not the results of the previous executions, but
8508 a non-zero number of errors/warnings thrown during parsing!
8509 */
8510 547408 thd->lex->keep_diagnostics = DA_KEEP_PARSE_ERROR;
8511 }
8512
8513
1/2
✓ Branch 0 taken 17229853 times.
✗ Branch 1 not taken.
17230597 thd->pop_diagnostics_area();
8514
8515 /*
8516 Check that if THD::sql_parser() failed either thd->is_error() is set, or an
8517 internal error handler is set.
8518
8519 The assert will not catch a situation where parsing fails without an
8520 error reported if an error handler exists. The problem is that the
8521 error handler might have intercepted the error, so thd->is_error() is
8522 not set. However, there is no way to be 100% sure here (the error
8523 handler might be for other errors than parsing one).
8524 */
8525
8526
8/12
✓ Branch 0 taken 7934 times.
✓ Branch 1 taken 17221919 times.
✓ Branch 2 taken 7934 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7934 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 7902 times.
✓ Branch 7 taken 32 times.
✓ Branch 8 taken 32 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 32 times.
✗ Branch 11 not taken.
17229853 assert(!mysql_parse_status || (mysql_parse_status && thd->is_error()) ||
8527 (mysql_parse_status && thd->get_internal_handler()));
8528
8529 /* Reset parser state. */
8530
8531 17229853 thd->m_parser_state = nullptr;
8532
8533 /* Restore creation context. */
8534
8535
3/4
✓ Branch 0 taken 741420 times.
✓ Branch 1 taken 16488433 times.
✓ Branch 2 taken 740891 times.
✗ Branch 3 not taken.
17229853 if (creation_ctx) creation_ctx->restore_env(thd, backup_ctx);
8536
8537 /* That's it. */
8538
8539
3/4
✓ Branch 0 taken 17221253 times.
✓ Branch 1 taken 8071 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17221093 times.
17229324 ret_value = mysql_parse_status || thd->is_fatal_error();
8540
8541
4/4
✓ Branch 0 taken 17221448 times.
✓ Branch 1 taken 7579 times.
✓ Branch 2 taken 11609205 times.
✓ Branch 3 taken 5612243 times.
17229027 if ((ret_value == 0) && (parser_state->m_digest_psi != nullptr)) {
8542 /*
8543 On parsing success, record the digest in the performance schema.
8544 */
8545
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11609205 times.
11609205 assert(thd->m_digest != nullptr);
8546
1/2
✓ Branch 0 taken 11610901 times.
✗ Branch 1 not taken.
11609205 MYSQL_DIGEST_END(parser_state->m_digest_psi,
8547 &thd->m_digest->m_digest_storage);
8548 }
8549
8550 17231401 return ret_value;
8551 17230723 }
8552
8553 /**
8554 @} (end of group Runtime_Environment)
8555 */
8556
8557 /**
8558 Check and merge "[ CHARACTER SET charset ] [ COLLATE collation ]" clause
8559
8560 @param [in] charset Character set pointer or NULL.
8561 @param [in] collation Collation pointer or NULL.
8562 @param [out] to Resulting character set/collation/NULL on success,
8563 untouched on failure.
8564
8565 Check if collation "collation" is applicable to character set "charset".
8566
8567 If "collation" is NULL (e.g. when COLLATE clause is not specified),
8568 then simply "charset" is returned in "to".
8569 And vice versa, if "charset" is NULL, "collation" is returned in "to".
8570
8571 @returns false on success,
8572 otherwise returns true and pushes an error message on the error stack
8573 */
8574
8575 1129354 bool merge_charset_and_collation(const CHARSET_INFO *charset,
8576 const CHARSET_INFO *collation,
8577 const CHARSET_INFO **to) {
8578
6/6
✓ Branch 0 taken 487585 times.
✓ Branch 1 taken 641769 times.
✓ Branch 2 taken 364513 times.
✓ Branch 3 taken 123072 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 1129349 times.
1493867 if (charset != nullptr && collation != nullptr &&
8579
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 364508 times.
364513 !my_charset_same(charset, collation)) {
8580 5 my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), collation->m_coll_name,
8581 5 charset->csname);
8582 5 return true;
8583 }
8584
8585
2/2
✓ Branch 0 taken 809069 times.
✓ Branch 1 taken 320280 times.
1129349 *to = collation != nullptr ? collation : charset;
8586 1129349 return false;
8587 }
8588
8589 304024 bool merge_sp_var_charset_and_collation(const CHARSET_INFO *charset,
8590 const CHARSET_INFO *collation,
8591 const CHARSET_INFO **to) {
8592
4/4
✓ Branch 0 taken 196011 times.
✓ Branch 1 taken 108013 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 196008 times.
304024 if (charset == nullptr && collation != nullptr) {
8593 3 my_error(
8594 ER_NOT_SUPPORTED_YET, MYF(0),
8595 "COLLATE with no CHARACTER SET in SP parameters, RETURNS, DECLARE");
8596 3 return true;
8597 }
8598 304021 return merge_charset_and_collation(charset, collation, to);
8599 }
8600